Struggling with "Array out of range" message

 

Hi,

I've never been particularly good at coding indicators, I'm getting an "array out of range" message with my current one. I've tried several things to fix this issue but none of them work, doesn't help that the internet is full of pre and post 600 information and examples which confuses me. Here is the full code for the indicator. Can anyone tell me what I am doing wrong please?

Best regards Steve 

 

#property indicator_chart_window    // Indicator is drawn in the main window
#property indicator_buffers 2       // Number of buffers
#property indicator_color1 Blue     // Color of the 1st line
#property indicator_color2 Red      // Color of the 2nd line

double Buf_0[],Buf_1[];             // Declaring arrays (for indicator buffers)
double CloseEurUsd[],CloseGbpUsd[],CloseAudUsd[],CloseAgUsd[],CloseAuUsd[];
//double CloseEurUsd2[], CloseGbpUsd2[] , CloseAudUsd2[] , CloseAgUsd2[], CloseAuUsd2[] ;

double VarEurUsd[],VarGbpUsd[],VarAudUsd[],VarAgUsd[],VarAuUsd[];
double Average[], Adj[], AdjPrice[];
//--------------------------------------------------------------------
int init() // Special function init()
  {
   SetIndexBuffer(0,Buf_0);         // Assigning an array to a buffer
   SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,2);// Line style
   SetIndexBuffer(1,Buf_1);         // Assigning an array to a buffer
   SetIndexStyle(1,DRAW_LINE,STYLE_DOT,1);// Line style
   return(0);                          // Exit the special funct. init()
  }
//--------------------------------------------------------------------
int start() // Special function start()
  {
   int i,// Bar index
   Counted_bars;                // Number of counted bars
//--------------------------------------------------------------------
   Counted_bars=IndicatorCounted(); // Number of counted bars
   i=Bars-Counted_bars-1;           // Index of the first uncounted
   ArrayResize( CloseEurUsd, Bars);
   ArrayResize(CloseGbpUsd, Bars);
   ArrayResize(CloseAudUsd, Bars);
   ArrayResize(CloseAgUsd, Bars);
   ArrayResize(CloseAuUsd, Bars);

   ArrayResize(VarEurUsd, Bars);
   ArrayResize(VarGbpUsd, Bars);
   ArrayResize(VarAudUsd, Bars);
   ArrayResize(VarAgUsd, Bars);
   ArrayResize(VarAuUsd, Bars);
   ArrayResize(Average, Bars);
   ArrayResize(Adj, Bars); 
   ArrayResize(AdjPrice, Bars);
 
   while(i>=0)                      // Loop for uncounted bars
     {
      CloseEurUsd[i] = iClose("EURUSD",PERIOD_D1,i);
      CloseGbpUsd[i] = iClose("GBPUSD",PERIOD_D1,i);
      CloseAudUsd[i] = iClose("AUDUSD",PERIOD_D1,i);
      CloseAgUsd[i] = iClose("XAGUSD",PERIOD_D1,i);
      CloseAuUsd[i] = iClose("XAUUSD",PERIOD_D1,i);

/*      CloseEurUsd2[i] = iClose("EURUSD",PERIOD_D1,i+1);
      CloseGbpUsd2[i] = iClose("GBPUSD",PERIOD_D1,i+1);
      CloseAudUsd2[i] = iClose("AUDUSD",PERIOD_D1,i+1);
      CloseAgUsd2[i] = iClose("XAGUSD",PERIOD_D1,i+1);
      CloseAuUsd2[i] = iClose("XAUUSD",PERIOD_D1,i+1);
*/
      VarEurUsd[i] = ((CloseEurUsd[i] - CloseEurUsd[i+1])/CloseEurUsd[i+1]);
      VarGbpUsd[i] = ((CloseGbpUsd[i] - CloseGbpUsd[i+1])/CloseGbpUsd[i+1]);
      VarAudUsd[i] = ((CloseAudUsd[i] - CloseAudUsd[i+1])/CloseAudUsd[i+1]);
      VarAgUsd[i] = ((CloseAgUsd[i] - CloseAgUsd[i+1])/CloseAgUsd[i+1]);
      VarAuUsd[i] = ((CloseAuUsd[i] - CloseAuUsd[i+1])/CloseAuUsd[i+1]);

      Average[i]=(VarEurUsd[i]+VarGbpUsd[i]+VarAudUsd[i]+VarAgUsd[i]+VarAuUsd[i])/5;

      Adj[i]=iClose(NULL,0,i+1)*Average[i];
      AdjPrice[i]=Adj[i]+iClose(NULL,0,i+1);

      Buf_0[i]=AdjPrice[i];             // Value of 0 buffer on i bar

      Buf_1[i]=Low[i];              // Value of 1st buffer on i bar
      i--;                          // Calculating index of the next bar
     }
//--------------------------------------------------------------------
   return(0);                          // Exit the special funct. start()
  }
//--------------------------------------------------------------------
 

Let's say there are 1000 bars on your chart. They are numbered from 0 to 999 (newest to oldest).

You write:

i=Bars-Counted_bars-1;   

So the first time you apply the indicator to the chart, Bars=1000 and Counted_bars=0. This means that i=999 (1000-0-1), which is the oldest bar on the chart.

But later on you want to reference i+1... but i+1 = 1000.  There is no bar with index 1000. Hence an array out of range.

      VarEurUsd[i] = ((CloseEurUsd[i] - CloseEurUsd[i+1])/CloseEurUsd[i+1]);
      VarGbpUsd[i] = ((CloseGbpUsd[i] - CloseGbpUsd[i+1])/CloseGbpUsd[i+1]);
      VarAudUsd[i] = ((CloseAudUsd[i] - CloseAudUsd[i+1])/CloseAudUsd[i+1]);
      VarAgUsd[i] = ((CloseAgUsd[i] - CloseAgUsd[i+1])/CloseAgUsd[i+1]);
      VarAuUsd[i] = ((CloseAuUsd[i] - CloseAuUsd[i+1])/CloseAuUsd[i+1]);

Incidentally, you might want to check for zero-divide problems. What if CloseEurUsd[i+1]==0? Or the others. Remember that iClose can return 0:

 Returned value

Close price value for the bar of specified symbol with timeframe and shift. If local history is empty (not loaded), function returns 0. To check errors, one has to call the GetLastError() function.

 

Thanks for your answer. I can never get my head around the way that bars are referenced in indicators, probably what causes me issues.

I changed it to i-1 which doesn't throw up the error but also doesn't create the indicator which I think is because i-1 in the array won't be populated yet as I'm counting down.

I'm trying to reference the prior bar with the i+1, which from testing with a much simpler indicator seemed to be the way to access the prior bar?

Best regards Steve 

 

Ah, the penny just dropped. It's basically the first bar on the chart that has the issue, as there is no prior bar. All the other bars will be fine. Ding!

I've changed it to 

i=Bars-Counted_bars-2;

Now I just have a zero divide issue. 

Best regards Steve 

 
Stevetrade: I've changed it to 
i=Bars-Counted_bars-2;
  1. Your max look back is one
     VarEurUsd[i] = ((CloseEurUsd[i] - CloseEurUsd[i+1])/CloseEurUsd[i+1])
  2. But now your
    CloseEurUsd[i+1]
    is zero because of your change. And after the initial pass, your change means it never updates again (i == -1) so you are using the open not close.
  3. Do your lookbacks right.
    for(int i = Bars - 1 - Counted_bars; i >= 0; --i){ // No look backs
          CloseEurUsd[i] = iClose("EURUSD",PERIOD_D1,i);
          CloseGbpUsd[i] = iClose("GBPUSD",PERIOD_D1,i);
          CloseAudUsd[i] = iClose("AUDUSD",PERIOD_D1,i);
          CloseAgUsd[i] = iClose("XAGUSD",PERIOD_D1,i);
          CloseAuUsd[i] = iClose("XAUUSD",PERIOD_D1,i);
    
    }
    for(int i = Bars - 1 - MathMax(1,Counted_bars); i >= 0; --i){ // max lookback
          VarEurUsd[i] = ((CloseEurUsd[i] - CloseEurUsd[i+1])/CloseEurUsd[i+1]);
          VarGbpUsd[i] = ((CloseGbpUsd[i] - CloseGbpUsd[i+1])/CloseGbpUsd[i+1]);
          VarAudUsd[i] = ((CloseAudUsd[i] - CloseAudUsd[i+1])/CloseAudUsd[i+1]);
          VarAgUsd[i] = ((CloseAgUsd[i] - CloseAgUsd[i+1])/CloseAgUsd[i+1]);
          VarAuUsd[i] = ((CloseAuUsd[i] - CloseAuUsd[i+1])/CloseAuUsd[i+1]);
    :
         Buf_1[i]=Low[i];              // Value of 1st buffer on i bar
    //   i--;                          // Calculating index of the next bar
    }
    

 

That seems to have sorted it. I had to download the history for all the pairs and then restrict the charts to only a thousand bars to prevent the other zero divide error caused by no history for some pairs but it seems to work now.

Thanks for the help folks.

Best regards Steve 

 

The indicator works and the values on a chart are correct. However when I attempt to use it in an EA, the values it's pulling out are suddenly incorrect. Is this some problem that it has accessing the corresponding data for the pairs that aren't the current chart?

Best regards Steve 

 
It would help if you post the code that calls the indicator and provides values that 'misbehave'.
 

Sorry!

This is all I'm doing to access the indicator from within the EA. All the values shown by the Comment seem wrong compared to a separate chart with the indicator on.

  double AVG = iCustom(NULL,0,"AVG USD",0,1);
   
   Comment ( AVG );   

 Best regards Steve

 

Still not enough :(

1) What are the extern-param,eters of this indicator?

2) How are the ext-Buffers defined.

Would you mind to post the OnInit() and the parameters of this indicator and the parameters of the indicator applied on the chart?

 

Hi,

I'm not providing any parameters to the indicator or carrying out anything in OnInit - which may of course be what is causing the issue.

The only external parameters I'm providing are for stop loss, take profit, magic number etc. The usual suspects for a basic EA.

Best regards Steve 

Reason: