Counts don't agree between rates_total and the oldest bar appearing on the chart.

 

I just wanted an indicator that would give me each bar's index value, to make debugging easier.

Simple code is at the bottom of the post.

I know rates_total is significantly more than the oldest bar that shows on the chart.

What I don't know is whether the chart is just limited to 99998 bars (or sometimes 99999) or if something funky is going on. The reason I'm suspicious is that I'm getting weird stuff happening in buffers past that magic 99999 point, and functions that key off the bar's index value (aka, "shift", like iTime, iClose, iHigh, etc.) are returning 0 for all bars between 99999 and rates_total.

This is really messing me up.

As you can see, with the crosshairs on the last bar of the chart,  the numbers just don't add up. (Including the fact that the code isn't picking up bar # 100234, but that's no big deal.)

I'll zoom in since those Comment() characters are so sketchy:


Can someone tell me what's going on here?



//+------------------------------------------------------------------+
//|                                                        BarID.mq5 |
//|                                                 Millard J Melnyk |
//+------------------------------------------------------------------+
#property copyright "Millard J Melnyk"
#property version   "1.00"
#property strict
#property indicator_chart_window

#property indicator_buffers   1
#property indicator_plots     0
//--- indicator buffers
double         NumerationBuffer[];
datetime       dtCurrBarTime=0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{  
//--- indicator buffers mapping
   SetIndexBuffer(0,NumerationBuffer,INDICATOR_DATA);

//--- set indexing for the buffer 
   ArraySetAsSeries(NumerationBuffer,true);

//--- set accuracy of showing in DataWindow
   IndicatorSetInteger(INDICATOR_DIGITS,0);

//--- how the name of the indicator arry is displayed in DataWindow
   IndicatorSetString(INDICATOR_SHORTNAME,"Bar#");

//---   
   return(INIT_SUCCEEDED);
   
}
//+------------------------------------------------------------------+
//| Custom indicator deinit function                         |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) 
{  
   Comment("");
   return;

}
//+------------------------------------------------------------------+
//| 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[])
{
  
//--- Set the time array to ArrayAsSeries = true so that time[0]
//    gives us the datetime of the new bar.
//
   ArraySetAsSeries(time,true);
   
   int iCnt=0;
   
//---  we'll store the time of the new bar when it comes.
//--- Initialized when declared: dtCurrBarTime=0;
//---
//--- If time of new bar differs from dtCurrBarTime
//

   if(dtCurrBarTime!=time[0])
   {
     //--- enumerate all bars from the current to the chart depth

      for(int ix=0;ix<rates_total-1;ix++) 
      {
         iCnt=ix;
         NumerationBuffer[ix]=ix;
      }
      
      dtCurrBarTime=time[0];
      Comment("rates_total<"+IntegerToString(rates_total)+"> last bar logged in buffer<"+IntegerToString(iCnt)+">");

   }

   return(rates_total);

}
 
Millard Melnyk: Can someone tell me what's going on here?
 for(int ix=0;ix<rates_total-1;ix++) 

Your image shows "rates_total<100235> last bar logged in buffer <100233>"

You loop runs from zero to rates_total-2. So the last update of iCnt will always be two less than rates_total.

 
William Roeder #:

Your image shows "rates_total<100235> last bar logged in buffer <100233>"

You loop runs from zero to rates_total-2. So the last update of iCnt will always be two less than rates_total.

HAHA missed that. Copy-n-paste snafu. It accounts for missing that last bar.

But that's not the actual problem.

The problem is that the last bar does not appear on the chart and I've no clue why.

But there's more. Theres a 99999 limit somewhere in the terminal, apparently. See my comment below.

 
William Roeder #:

Your image shows "rates_total<100235> last bar logged in buffer <100233>"

You loop runs from zero to rates_total-2. So the last update of iCnt will always be two less than rates_total.

William, look in the data window. That little red bar at the far left of the chart as far back as it goes is bar #99998. You can see the crosshairs on it and the clear readout on the "Bar#" line.

THAT is the problem. How can there be 100235 rates and I only get to see 99998 or 99999? It's not just a limit on how many bars you can have on a chart. It affects a bunch of stock functions, too. See below.

 

OK, a little more info. There was reason for suspicion.

I wrote a little script to test whether there's just a 99999 limit on charts, or there's something deeper. Turns out it's deeper.

Too bad I've spent two full days trying to find the bug in my code when it was never there.

Here's the script:

Mak##r3asy!#property strict
//#property script_show_inputs

input ENUM_INDICATOR       eInd = IND_MA;
input ENUM_APPLIED_PRICE   eAP  = PRICE_MEDIAN;

#include <Chart routines shortlist MJM.mqh>
#include <Indicator Utils MJM.mqh>
#include <EnumToArray.mqh>
#include <Fudge Factors MJM.mqh>

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{  
   
   double dOpenPrc;
   double dHighPrc;
   double dLowPrc;
   double dClsePrc;
   datetime dtDT;
   int iBarCNT             = iBars(_Symbol,_Period);
   
Print(" ");
Print(" ");
Print("["+__FILE__+" ["+__FUNCTION__+"] LINE "+(string)__LINE__+" MS: "+(string)GetMicrosecondCount()+" - ",
   "Testing iTime, iOpen, etc. - Symbol<",_Symbol,"> Period<",_Period,"> iBarCNT<",iBarCNT,">");
Print(" ");
   for(int ix = 99997;ix<100010;ix++)
   {
      dtDT                 = iTime(_Symbol,_Period,ix);
      dOpenPrc             = iHigh(_Symbol,_Period,ix);
      dHighPrc             = iLow(_Symbol,_Period,ix);
      dLowPrc              = iLow(_Symbol,_Period,ix);
      dClsePrc             = iClose(_Symbol,_Period,ix);

Print("["+__FILE__+" ["+__FUNCTION__+"] LINE "+(string)__LINE__+" MS: "+(string)GetMicrosecondCount()+" - ",
   "  ix<",ix,
   "> iTime<",dtDT,
   "> iOpen<",dOpenPrc,
   "> iHigh<",dHighPrc,
   "> iLow<",dLowPrc,
   "> iClose<",dClsePrc,
   "> "
   );
   
   }

   int iii = 0;
}


And here's the output, minus the timestamp:

Test 20 (USDJPY,H1)     [Test 20.mq5 [OnStart] LINE 27 MS: 351 - Testing iTime, iOpen, etc. - Symbol<USDJPY> Period<16385> iBarCNT<100236>
Test 20 (USDJPY,H1)      
Test 20 (USDJPY,H1)     [Test 20.mq5 [OnStart] LINE 38 MS: 358 -   ix<99997> iTime<2008.02.26 00:00:00> iOpen<108.1> iHigh<107.96> iLow<107.96> iClose<108.05> 
Test 20 (USDJPY,H1)     [Test 20.mq5 [OnStart] LINE 38 MS: 363 -   ix<99998> iTime<2008.02.25 23:00:00> iOpen<108.12> iHigh<108.0> iLow<108.0> iClose<108.1> 
Test 20 (USDJPY,H1)     [Test 20.mq5 [OnStart] LINE 38 MS: 367 -   ix<99999> iTime<2008.02.25 22:00:00> iOpen<108.1> iHigh<108.02> iLow<108.02> iClose<108.05> 
Test 20 (USDJPY,H1)     [Test 20.mq5 [OnStart] LINE 38 MS: 370 -   ix<100000> iTime<1970.01.01 00:00:00> iOpen<0.0> iHigh<0.0> iLow<0.0> iClose<0.0> 
Test 20 (USDJPY,H1)     [Test 20.mq5 [OnStart] LINE 38 MS: 374 -   ix<100001> iTime<1970.01.01 00:00:00> iOpen<0.0> iHigh<0.0> iLow<0.0> iClose<0.0> 
Test 20 (USDJPY,H1)     [Test 20.mq5 [OnStart] LINE 38 MS: 376 -   ix<100002> iTime<1970.01.01 00:00:00> iOpen<0.0> iHigh<0.0> iLow<0.0> iClose<0.0> 
Test 20 (USDJPY,H1)     [Test 20.mq5 [OnStart] LINE 38 MS: 379 -   ix<100003> iTime<1970.01.01 00:00:00> iOpen<0.0> iHigh<0.0> iLow<0.0> iClose<0.0> 
Test 20 (USDJPY,H1)     [Test 20.mq5 [OnStart] LINE 38 MS: 381 -   ix<100004> iTime<1970.01.01 00:00:00> iOpen<0.0> iHigh<0.0> iLow<0.0> iClose<0.0> 
Test 20 (USDJPY,H1)     [Test 20.mq5 [OnStart] LINE 38 MS: 383 -   ix<100005> iTime<1970.01.01 00:00:00> iOpen<0.0> iHigh<0.0> iLow<0.0> iClose<0.0> 
Test 20 (USDJPY,H1)     [Test 20.mq5 [OnStart] LINE 38 MS: 385 -   ix<100006> iTime<1970.01.01 00:00:00> iOpen<0.0> iHigh<0.0> iLow<0.0> iClose<0.0> 
Test 20 (USDJPY,H1)     [Test 20.mq5 [OnStart] LINE 38 MS: 388 -   ix<100007> iTime<1970.01.01 00:00:00> iOpen<0.0> iHigh<0.0> iLow<0.0> iClose<0.0> 
Test 20 (USDJPY,H1)     [Test 20.mq5 [OnStart] LINE 38 MS: 390 -   ix<100008> iTime<1970.01.01 00:00:00> iOpen<0.0> iHigh<0.0> iLow<0.0> iClose<0.0> 
Test 20 (USDJPY,H1)     [Test 20.mq5 [OnStart] LINE 38 MS: 392 -   ix<100009> iTime<1970.01.01 00:00:00> iOpen<0.0> iHigh<0.0> iLow<0.0> iClose<0.0> 


As you can see, we have a bar count of 100236. Nothing shows up on the chart past bar 99998 or 99999, but that's not the real problem. All of those functions start dropping ZEROES for all the bars past 99999.

This is a serious problem. Not just those functions, but other functions are affected, too, but I thought showing you these should be enough for this post.

So what the f*** and why, and when will this be fixed?

What's the point of feeding us data for bars that we can't see and can't calculate, even though they've got data (as proven by looking at any of the OnCalculate arrays while testing an indicator)?