//+------------------------------------------------------------------+
//|                                        test indicatorCounted.mq4 |
//|                    Copyright © 2012, pips4life @ forexfactory.com|
//+------------------------------------------------------------------+
#property copyright "Copyright © 2012, pips4life"
#property link      "http://forexfactory.com/pips4life"

#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();   
   int    myCounted_bars = myIndicatorCounted();
   
   Alert("DEBUG counted=",counted_bars,"  myIndicatorCounted=",myCounted_bars,"  Bars=",Bars );
   
   return(0);
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
// Add this section of code to your indicators, and rename your calls that say "IndicatorCounted()"
// to say instead, "myIndicatorCounted()"
int myIndicatorCounted()
{
   // This function should be similar to IndicatorCounted, except that it's designed to work with "offline"
   // charts.  In those charts, the regular IndicatorCounted always returns "0" which is wrong.
   // NOTE!  This function has not been fully tested, especially at boundary conditions such as when
   // your chart has the maximum #-of-bars, and so "Bars" may very well stay the same with every new bar. (FYI, I
   // don't know how the regular IndicatorCounted works at this same boundary too).
   // Another untested condition is how it compares when restarting MT4 after being off for awhile, after several
   // new bars have elapsed.  MT4 may start, run it's 1st tick, and THEN update a cluster of new bars all at once.
   // I *think* this should work, but it may not strictly be identical to the regular IndicatorCounted function.
   // In fact, the code below will most like return one of three values for offline charts:
   //    Bars-1   (This would be a normal IC value during the current bar)
   //    Bars-2   (This would be a normal IC value for the FIRST tick of a new bar)
   //    0        (This is not "normal IC" behavior, but if there are 2-or-more new bars detected, a "safe" assumption
   //                 is made to just pretend that "0" bars have been counted.  As it is a rare occurence, it should not
   //                 adversely affect CPU loading).
   
   // There is at least one other difference for offline charts, and that is that a chart "Refresh" will NOT return the 
   // value of "0" to force a recalculation of all values.  An MT4 re-start would be one possible workaround, or you 
   // could delete and re-add the indicator(s) that you want to fully recalculate.
   
   // Report any problems in thread: http://www.forexfactory.com/showthread.php?t=206301
   
   datetime counted; // Use datetime for long-int precision.  "int" doesn't work for calculations with "timeBar0" below
   static bool     Normal_IC_Works; // Normally initializes to false
   
   counted = IndicatorCounted();
   if (counted > 0 || Normal_IC_Works) 
   {
      // If a non-zero value has ever occurred, this is a regular (non-offline) chart, so ALWAYS USE the regular IndicatorCounted()
      // value.  This means that a manual chart "Refresh" command will cause a value of "0", and that "0" will be returned here.
      Normal_IC_Works = true; 
      return(counted);
   }
   
   // If the code is here, it must be an offline chart, OR, it's the 1st time through on a regular chart.
   
   datetime        timeBar0;
   static datetime last_timeBar0;
   static int      last_Bars;
   

   // If it seems there are 2-or-more NEW bars, make the safer assumption that ALL bars are new and that none have been counted.
   // If you dont't like this assumption, just comment it out and replace it with "if (false) counted=0;".  The true number will be calculated further below.
   if ( Bars - last_Bars >= 2) counted = 0;
   else
   {
      timeBar0 = Time[0];
      if (timeBar0 == last_timeBar0) counted = Bars-1;
      else
      {
         // Probably this section will only return Bars-2.  The only way it could be more and still be here in the code
         // is if the chart has the maximum allowed "Bars", but then the chart all-at-once added several new bars.  If THAT
         // happens, make the safer assumption that ALL bars are new and that none have been counted.
         if ((timeBar0 - last_timeBar0)/(60*Period() ) == 1) counted = Bars-2;
         else counted = 0;
            
         // Instead of the above 2 lines, one could calculated the actual # of new bars using this line:
         //counted = MathMax(0,Bars - 1 - (timeBar0 - last_timeBar0)/(60*Period() ) );
      }
   }
   
   last_Bars = Bars;
   last_timeBar0 = timeBar0;
   return(counted);
}  // end of myIndicatorCounted
//+------------------------------------------------------------------+

