//+------------------------------------------------------------------+
//|                                      P4L test_Bars_at_newbar.mq4 |
//|                                                        Pips4Life |
//|                               https://forexfactory.com/pips4life |
//+------------------------------------------------------------------+
#property copyright "Pips4Life"
#property link      "https://forexfactory.com/pips4life"
#property version   "1.00"
#property strict
#property indicator_chart_window

// 2017-DEC-04 by pips4life.  MT4 bug is if prev_calculated > Bars, not just if prev_calculated==last_Bars.
// 2017-DEC-03 by pips4life   Test whether "Bars" ever reduces on a live chart. 
//   In my experience, it ONLY grows larger, +1 for each newbar.  This is the test of that assumption!
//   AlertMode=3(default).  This will ONLY alert if it detects the unexpected result of Bars reducing value.
//      If that occurs, then "prev_calculated" is ALSO checked, whether it changed correctly or not.
//      If prev_calculate == last_Bars and Bars<last_Bars, THIS IS AN MT4 BUG and should be reported!
//   AlertMode=2  This will alert like #3 AND also when the Bars-lastBars !=1  (0 would be unexpected!

input string FYI_AlertMode_means____ = "1=each_newbar, 2=if_NOT_onebar, 3=if_Bars_REDUCED_unexpectedly";
input int    AlertMode_123 = 3;

string CHART_str;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
      CHART_str = StringConcatenate(Symbol(),",",StringSubstr(EnumToString((ENUM_TIMEFRAMES)Period()),7),": ");

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   static datetime last_bartime;
   bool newbar = false;

   if(last_bartime > 0 && time[0] != last_bartime) newbar = true;
   last_bartime = time[0];
   
   static int last_Bars = Bars;
   if(AlertMode_123 == 1 && newbar) Alert(CHART_str,"At new bar, Bars=",Bars,"  and Bars has changed by ",Bars-last_Bars," ( '1' is typical). If >1, maybe a cluster of new bars just updated? (Common on MT4 restart, or if connection is interrupted then reconnects)");
   if(AlertMode_123 == 2 && newbar && Bars-last_Bars >= 1) Alert(CHART_str,"At new bar, Bars=",Bars,"  and Bars has UNUSUALLY changed by ",Bars-last_Bars," rather than the typical '1'. If >1, maybe a cluster of new bars just updated??");
   if(AlertMode_123 >= 1 && newbar && Bars-last_Bars == 0) 
   {
      // The "..." alert executes FIRST for better readability of the two consecutive alerts of the popup.
      if(prev_calculated == last_Bars) Alert(CHART_str,"... MT4 BUG?? prev_calculated=",prev_calculated," which is == last_Bars! This bug should be reported! (says http://forexfactory.com/pips4life  Also, what build number??)");
      Alert(CHART_str,"MT4 BUG?? At new bar, Bars=",Bars," which ALSO equals last_Bars(!) rather than the usual 'Bars-1'. Indicators may fail to update! (Fyi prev_calculated=",prev_calculated," which is BEST if <Bars, BAD if ==Bars!) Check your Max-bars-on-chart");
   }
   if(AlertMode_123 >= 1 && newbar && Bars-last_Bars < 0) 
   {
      // AFAIK (this is pips4life), this Alert should never occur, but if it does, coders should be aware.
      // Furthermore, if this occurs, the value of "prev_calculated" is of keen interest!  It ought to be 0, IMO,
      //  but might be Bars-1 (possibly OK for some indicators).  If it is last_Bars, see below...
      //
      // If prev_calculated == last_Bars AND this is > Bars, that's a BIG problem and an MT4 bug!  Why?  
      //   Programs commonly use:  limit=Bars-prev_calculated  (usually 0 within Bar0, then 1 for a new bar).
      //   Then calculations are updated with a for-loop:  for(int i=limit; i>=0; i--) { ... bar-by-bar calculations... }
      //   If "limit < 0", most indicators do NOT expect a limit<0   !!  The code may fail, or at least may not update properly!
      // If this error occurs, please report the bug to MetaTrader, and/or inform http://forexFactory.com/pips4life  and I'll do it if necessary.  (as of 2017-Dec-03).
      //
      if(prev_calculated > Bars) Alert(CHART_str,"... MT4 BUG?? prev_calculated=",prev_calculated," which is > Bars! This bug should be reported! (says http://forexfactory.com/pips4life  Also, what build number??)");
      if(prev_calculated != 0) Alert(CHART_str,"... ALSO OF CONCERN IS prev_calculated=",prev_calculated," but ought to be 0 to refresh all calculations!  (Possibly Bars-1 is ok)");
      Alert(CHART_str,"... How did #Bars go down?? Was max-bars-on-chart limit finally re-imposed?? (Fyi: prev_calculated=",prev_calculated,")");
      Alert(CHART_str,"WARNING for developers: At new bar, Bars-last_Bars is NEGATIVE (",Bars-last_Bars,")  for Bars=",Bars," and last_Bars=",last_Bars);
   }
   last_Bars = Bars;
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
