Critical error Array out of range help

Am trying to translate an MQL4 Indicator of mine to MQL5.

It loads and initially shows the Indicator lines and arrows correctly, but then refuses to update on new ticks.

Debug gives array out of range error on all lines in which arrays use [i-1]. Have also tried [i+1] with the same result.

//--------------------------------------------------------------------
// Bars.mq4 
//--------------------------------------------------------------------
#property strict
#property indicator_chart_window   
#property indicator_buffers 10
#property indicator_plots   6
#property indicator_label1  "Histogram_1"
#property indicator_type1   DRAW_HISTOGRAM2
#property indicator_color1  clrAqua
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1 
#property indicator_label2  "Histogram_2"
#property indicator_type2   DRAW_HISTOGRAM2
#property indicator_color2  clrMagenta
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
#property indicator_label3  "Histogram_3"
#property indicator_type3   DRAW_HISTOGRAM2
#property indicator_color3  clrMediumPurple
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1
#property indicator_label4  "Histogram_4"
#property indicator_type4   DRAW_HISTOGRAM2
#property indicator_color4  clrBlack
#property indicator_style4  STYLE_SOLID
#property indicator_width4  6
#property indicator_label5  "Dot_1"
#property indicator_type5   DRAW_ARROW
#property indicator_color5  clrBlue
#property indicator_width5  3
#property indicator_label6  "Dot_2"
#property indicator_type6   DRAW_ARROW
#property indicator_color6  clrWhite
#property indicator_width6  1 
//--------------------------------------------------------------------
double Buf_0[], Buf_1[], Buf_2[], Buf_3[], Buf_4[], Buf_5[], Buf_6[], Buf_7[], Buf_8[], Buf_9[];
//--------------------------------------------------------------------
int OnInit()                       
  {
   SetIndexBuffer(0, Buf_0, INDICATOR_DATA);
   SetIndexBuffer(1, Buf_1, INDICATOR_DATA);            
   SetIndexBuffer(2, Buf_2, INDICATOR_DATA);         
   SetIndexBuffer(3, Buf_3, INDICATOR_DATA); 
   SetIndexBuffer(4, Buf_4, INDICATOR_DATA);         
   SetIndexBuffer(5, Buf_5, INDICATOR_DATA); 
   SetIndexBuffer(6, Buf_6, INDICATOR_DATA);         
   SetIndexBuffer(7, Buf_7, INDICATOR_DATA); 
   SetIndexBuffer(8, Buf_8, INDICATOR_DATA);
   SetIndexBuffer(9, Buf_9, INDICATOR_DATA);
//
   return(INIT_SUCCEEDED);                         
  }
//--------------------------------------------------------------------
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[])                         
  {
   for(int i = rates_total - prev_calculated - 1; i >= 0; i--)
     { 
     if (((High[i] + Low[i]) / 2) > ((High[i-1] + Low[i-1]) / 2))
     { 
      Buf_0[i] = High[i];
      Buf_1[i] = Low[i];
     }                
     else
     {
      Buf_0[i] = 0;
      Buf_1[i] = 0;
     }  
//
     if (((High[i] + Low[i]) / 2) < ((High[i-1] + Low[i-1]) / 2))
     { 
      Buf_2[i] = High[i];
      Buf_3[i] = Low[i];
     }                      
     else
     {
      Buf_2[i] = 0;
      Buf_3[i] = 0;
     }        
// 
     if (((High[i] + Low[i]) / 2) == ((High[i-1] + Low[i-1]) / 2)) 
     {
      Buf_4[i] = High[i];
      Buf_5[i] = Low[i]; 
     }                     
     else
     {
      Buf_4[i] = 0; 
      Buf_5[i] = 0;
     }       
//                                    
      Buf_6[i-1] = ((High[i-1] + Low[i-1]) / 2) + 0.1;
      Buf_7[i-1] = ((High[i-1] + Low[i-1]) / 2) - 0.1; 
                 
      Buf_8[i-1] = (High[i-1] + Low[i-1] + Close[i-1] + Open[i-1] + Close[i-1] + Close[i-1]) / 6; 
      Buf_9[i-1] = (High[i-1] + Low[i-1] + Close[i-1] + Open[i-1] + Close[i-1] + Close[i-1]) / 6;
     }
//
   return(0);                   

Any ideas what is happening here? Does MQL5 possibly have a different syntax for decremented within the array? Have not been able to find any documentation on this yet.

for(int i = rates_total - prev_calculated - 1; i >= 0; i--)

At the end of this loop, i = 0

If you subtract 1, you get -1

There is no index -1, so your array is out of range.

At the start of this loop, i = rates_total - 1

If you add 1, you get rates_total.

There is no index equal to rates_total. The biggest index is rates_total - 1 (because the numbering starts from 0 not 1).

Generally speaking it is bad to use i - 1 with timeseries as it looks into the future.

Keep with i + 1 but limit your loop.

Here is a good post about how to do lookbacks correctly.

(If you want to use i+1 then your lookback is 1).


PS please use the SRC button when you post code - it makes it much easier to read! I’ve edited your post for you.

Thank you very much glaff! That was amazingly quick. Time to study that post and get into doing MQL5 correctly.

IndicatorDigits()

I use NormalizeDouble() quite often.

Example:

double something = 0.123456789;
double someother = NormalizeDouble(something,2);
Comment("Something = "+(string)something+"\nSomeother: "+(string)someother);

The output looks like this:

Both those methods (MathRound and NormalizeDouble) do not change the output of the data window. For that, you have to use IndicatorDigits() for MQL4 or IndicatorSetInteger(INDICATOR_DIGITS,x) for both MQL4 and MQL5