Array Out Of Range - help needed

Hello, a simple problem here, if you are an expert you will find this problem within seconds…my indicator always gets error “Array out of range” when trying to test it. I just dont know why…


#property indicator_separate_window

#property indicator_buffers 3
#property indicator_plots   3

#property indicator_type1   DRAW_LINE
#property indicator_color1  C'127,191,127'
#property indicator_style1  STYLE_SOLID
#property indicator_label1  "Negative Deviation"
#property indicator_type2   DRAW_LINE
#property indicator_color2  C'191,127,127'
#property indicator_style2  STYLE_SOLID
#property indicator_label2  "Positive Deviation"
#property indicator_type3   DRAW_LINE
#property indicator_color3  C'191,127,127'
#property indicator_style3  STYLE_SOLID
#property indicator_label3  "Spread"
#property indicator_width3  2

#define DATA_LIMIT 200

#include <MovingAverages.mqh>

double spreadLine[];
double upperDeviation[];
double lowerDeviation[];

void OnInit()
  {
   SetIndexBuffer(0,spreadLine,INDICATOR_CALCULATIONS);
   SetIndexBuffer(1,upperDeviation,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,lowerDeviation,INDICATOR_CALCULATIONS);
//   hATR=iATR(NULL,ATRtimeframe,ATRper);
  }
  
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[])
      {
      double closePricesEURUSD[];
      double closePricesGBPUSD[];
      double logEURUSD[];
      double logGBPUSD[];


//--- check for rates total
   if(rates_total<DATA_LIMIT)
      return(0); // not enough bars for calculation      
      
      CopyClose(NULL,timeFrame,0,rates_total-100,closePricesEURUSD);
      CopyClose(currency2,timeFrame,0,rates_total-100,closePricesGBPUSD);

      for(int j=0; j<rates_total-100; j++)
            {
            double sum_Xi=0.0;
            double sum_Yi=0.0;
            double sum_Xi_squared=0.0;
            double sum_Yi_squared=0.0;
            double sumOfProductXiYi=0.0;
	                

            for(int i=j; i<j+100; i++)
                  {
                  logEURUSD[i]=log(closePricesEURUSD[i]); // HERE IT SAYS OUT OF ARRAY
                  logGBPUSD[i]=log(closePricesGBPUSD[i]); 
                  sum_Xi = sum_Xi + logEURUSD[i];
                  sum_Yi = sum_Yi + logGBPUSD[i];
                  sum_Xi_squared = sum_Xi_squared + logEURUSD[i]*logEURUSD[i];
                  sum_Yi_squared = sum_Yi_squared + logGBPUSD[i]*logGBPUSD[i];
                  sumOfProductXiYi = sumOfProductXiYi + logEURUSD[i]*logGBPUSD[i];
                  }

return (rates_total);

}



tried everything from resizing array, setasseries, change beginning condition of “for” loop to j=1, and also trying to give the array a constant size when defining it. Help is appreciated!

      logEURUSD[i]=log(closePricesEURUSD[i]); // HERE IT SAYS OUT OF ARRAY

i is varying between j and j+100 (excluded)

j is varying between 0 and rates_total-100 (excluded)

so i is from 0 to rates_total-1 (excluded)

but your array closePricesEURUSD[] is at best of size rates_total-100, so from 0 to rates_total-100 (excluded) :

CopyClose(NULL,timeFrame,0,rates_total-100,closePricesEURUSD);

When i is >= rates_total-100 you get an “array out of range”.

You should also check returned value of CopyClose().

thank you, I already changed this beforehand because my initial boundaries were also not working. I fixed it now to this:

CopyClose(NULL,timeFrame,0,rates_total,closePricesEURUSD);

      for(int j=0; j<=rates_total-n; j++)
            {

            for(int i=j; i<j+n-1; i++)
                  {
                  logEURUSD[i]=log(closePricesEURUSD[i]);

so now i goes from 0 to rates_total-1, and my CopyClose array should be large enough but still I get the error “array out of range”. Also I Printed the values for each close price closePricesEURUSD[0], closePricesEURUSD[1] and closePricesEURUSD[2], and they never change, always constant, I thought they are re-calculated on a new bar? Or is array element [0] the close price of the oldest bar in the history? I thought [0] is the actual bar.

  logEURUSD[i]=log(closePricesEURUSD[i]); // HERE IT SAYS OUT OF ARRAY

i is varying between j and j+100 (excluded)

j is varying between 0 and rates_total-100 (excluded)

so i is from 0 to rates_total-1 (excluded)

but your array closePricesEURUSD[] is at best of size rates_total-100, so from 0 to rates_total-100 (excluded) :

CopyClose(NULL,timeFrame,0,rates_total-100,closePricesEURUSD);

When i is >= rates_total-100 you get an “array out of range”.

You should also check returned value of CopyClose().

What is happening if CopyClose() copies less than rates_total values ? Always check the returned value.

I added a check for the returned value, it returns the rates_total value, so everythign is okay but the error is still there. So I made it easier to find the error, by deleting the two for-loops and just use on single line:

double closePricesEURUSD[];

if(CopyClose(NULL,timeFrame,0,rates_total,closePricesEURUSD) < rates_total ) 
       { 
       ArrayResize(closePricesEURUSD,rates_total,0);
       }  

logEURUSD[0]=log(closePricesEURUSD[0]); // --> this line causes error "array out of range"

this also leads to an error “array out of range”, it seems as if the problem lies within the value of element 0.

problem solved…I added ArrayResize(logEURUSD,rates_total);

now it works. If someone knows why this is necessary and why the array is not automatically adjusted to fit the size of the array closePricesEURUSD[] then please tell me, otherwise thank you all for helping me out!

The question is why you are thinking it’s not necessary. A dynamic array always need to be resized. Except for buffers and when CopyXXX() functions are used where it’s done automatically.

    CopyClose(NULL,timeFrame,0,rates_total-100,closePricesEURUSD);
      CopyClose(currency2,timeFrame,0,rates_total-100,closePricesGBPUSD);
:
                  logEURUSD[i]=log(closePricesEURUSD[i]); // HERE IT SAYS OUT OF ARRAY
                  logGBPUSD[i]=log(closePricesGBPUSD[i]); 

If timeFrame isn’t the current chart period, this fails. rates_total is the current chart.

If currency2 isn’t the current chart, this fails. rates_total is the current chart

You are mixing apples and oranges.