Array out of range

 

Hi


I am keep getting array out of range errors.


Could anyone please tell me how to fix this?


Indicator seems to plot well the fly price, moving averages but when I add the code for standard deviation calculation, I keep getting the error message. 


Much appreciated for any help

//+------------------------------------------------------------------+
//|                                                    Fly Price.mq4 |
//|                                                   Hyun soo Hwang |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Hyun soo Hwang"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_level1     0
#property indicator_buffers 5
#property indicator_color1     Red
#property indicator_color2     LightSeaGreen
#property indicator_color3     LightBlue
#property indicator_color4     Blue
#property indicator_color5     Blue

//--- buffers
double ExtFlyBuffer[];
double Ext10MaBuffer[];
double Ext20MaBuffer[];
double ExtUpperBandBuffer[];
double ExtLowerBandBuffer[];


double ExtStdevBuffer[];

//--- variables
int limit, i, x, y;
double total;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtFlyBuffer);
   SetIndexStyle(0,DRAW_LINE, STYLE_SOLID, 2);
   SetIndexLabel(0,"Fly Close");
   
   SetIndexBuffer(1,Ext10MaBuffer);
   SetIndexStyle(0,DRAW_LINE, STYLE_SOLID, 1);
   SetIndexLabel(1,"10 MA");
   
   SetIndexBuffer(2,Ext20MaBuffer);
   SetIndexStyle(0,DRAW_LINE, STYLE_SOLID, 1);
   SetIndexLabel(2,"20 MA");
   
   SetIndexBuffer(3,ExtUpperBandBuffer);
   SetIndexStyle(0,DRAW_LINE, STYLE_DASH, 1);
   SetIndexLabel(3,"Upper Band");
   
   SetIndexBuffer(4,ExtLowerBandBuffer);
   SetIndexStyle(0,DRAW_LINE, STYLE_DASH, 1);
   SetIndexLabel(4,"Lower Band");
   
//---
   return(INIT_SUCCEEDED);
  }
 
//+------------------------------------------------------------------+
//| 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[])
  {
 
//--- Find number of bars to fill (aka find Limit)
   int counted_bars=IndicatorCounted(); // IndicatorCounted returns number of bars not changed since the indicator had been launched last
   if(counted_bars<0) return(-1); // To check for errors
   if(counted_bars>=0) counted_bars--; // Minus 1 so as to always recount the last bar. Last bar may be formed incompletely
   
   limit=Bars-counted_bars; // Bars represent number of bars in the chart

//--- Main Calculation 
   for(i=limit-1; i>=0; i++) {
      ///--- Fly price
      ExtFlyBuffer[i] = flyPrice(i);
      
      ///--- Moving averages
      Ext10MaBuffer[i] = MA(i, 10);
      Ext20MaBuffer[i] = MA(i, 20);
      
      //--- Standard Deviation    
      ExtStdevBuffer[i] = Stdev(i,ExtFlyBuffer,Ext20MaBuffer,20);
      ExtUpperBandBuffer[i] = Ext20MaBuffer[i] + ExtStdevBuffer[i];
      ExtLowerBandBuffer[i] = Ext20MaBuffer[i] - ExtStdevBuffer[i];
      
    }
      
   return(rates_total);
//--- return value of prev_calculated for next call  
  }
  
//+------------------------------------------------------------------+

//--- Functions

double flyPrice(int k) {
   
   double flyPrice = (iClose("EURGBP", 0, k)-iClose("EURUSD", 0, k))-(iClose("EURUSD", 0, i)-iClose("GBPUSD", 0, k));
   
   return(flyPrice);

}

double MA(int m, int period1) {
   double sum1 = 0;
   double ma1;
   for(x=m; x<m+period1; x++) {
            sum1 = sum1 + flyPrice(x);
         }

   ma1 = sum1/period1; // Sum of prices divided number of bars gives us the SMA on closing price 
   return(ma1);        
   
}

double Stdev(int pos, double &price[], double &MA[], int period) {

   double StdevTemp=0.0;
   
   for (y=pos; y<pos+period; y++) {
      StdevTemp +=MathPow(price[pos]-MA[pos],2);
      StdevTemp = MathSqrt(StdevTemp/period);
   }
   
   return(StdevTemp);
}

 

StdevBuffer[] should be set as index:

   SetIndexBuffer(4,ExtLowerBandBuffer);
   SetIndexStyle(4,DRAW_LINE,STYLE_DASH,1);
   SetIndexLabel(4,"Lower Band");
   
   IndicatorBuffers(6);
   SetIndexBuffer(5,ExtStdevBuffer);

Main loop should be counting down:

   //int counted_bars=IndicatorCounted(); // IndicatorCounted returns number of bars not changed since the indicator had been launched last
   if(rates_total<20 || prev_calculated<0) return(0); // To check for errors
   //if(counted_bars>0) counted_bars--; // Minus 1 so as to always recount the last bar. Last bar may be formed incompletely

   limit=(prev_calculated==0)?rates_total-1:rates_total-prev_calculated; // Bars represent number of bars in the chart

//--- Main Calculation 
   for(i=limit; i>=0 && !_StopFlag; i--) 
     {
 
Ernst Van Der Merwe:

StdevBuffer[] should be set as index:

Main loop should be counting down:

Thank you so much for your help!

Now its drawing the band as well. But they seem a bit too wide than I expected and prices never seem to cross any. Could you please have a look at the standard deviation function if I wrote correctly?

//+------------------------------------------------------------------+
//|                                                    Fly Price.mq4 |
//|                                                   Hyun soo Hwang |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Hyun soo Hwang"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_level1     0
#property indicator_buffers 5
#property indicator_color1     Red
#property indicator_color2     LightSeaGreen
#property indicator_color3     LightBlue
#property indicator_color4     Blue
#property indicator_color5     Blue

//--- buffers
double ExtFlyBuffer[];
double Ext10MaBuffer[];
double Ext20MaBuffer[];
double ExtUpperBandBuffer[];
double ExtLowerBandBuffer[];


double ExtStdevBuffer[];

//--- variables
int limit, i, x, y;
double total;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtFlyBuffer);
   SetIndexStyle(0,DRAW_LINE, STYLE_SOLID, 2);
   SetIndexLabel(0,"Fly Close");
   
   SetIndexBuffer(1,Ext10MaBuffer);
   SetIndexStyle(0,DRAW_LINE, STYLE_SOLID, 1);
   SetIndexLabel(1,"10 MA");
   
   SetIndexBuffer(2,Ext20MaBuffer);
   SetIndexStyle(0,DRAW_LINE, STYLE_SOLID, 1);
   SetIndexLabel(2,"20 MA");
   
   SetIndexBuffer(3,ExtUpperBandBuffer);
   SetIndexStyle(0,DRAW_LINE, STYLE_DASH, 1);
   SetIndexLabel(3,"Upper Band");
   
   SetIndexBuffer(4,ExtLowerBandBuffer);
   SetIndexStyle(0,DRAW_LINE, STYLE_DASH, 1);
   SetIndexLabel(4,"Lower Band");
   
   IndicatorBuffers(6);
   SetIndexBuffer(5, ExtStdevBuffer);
   
//---
   return(INIT_SUCCEEDED);
  }
 
//+------------------------------------------------------------------+
//| 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[])
  {
 
//--- Find number of bars to fill (aka find Limit)
   //int counted_bars=IndicatorCounted(); // IndicatorCounted returns number of bars not changed since the indicator had been launched last
   if(rates_total<20 || prev_calculated<0) return(0); // To check for errors
   //if(counted_bars>0) counted_bars--; // Minus 1 so as to always recount the last bar. Last bar may be formed incompletely

   limit=(prev_calculated==0)?rates_total-1:rates_total-prev_calculated; // Bars represent number of bars in the chart

//--- Main Calculation 
   for(i=limit; i>=0 && !_StopFlag; i--) {
      ///--- Fly price
      ExtFlyBuffer[i] = flyPrice(i);
      
      ///--- Moving averages
      Ext10MaBuffer[i] = MA(i, 10);
      Ext20MaBuffer[i] = MA(i, 20);
      
      //--- Standard Deviation    
      ExtStdevBuffer[i] = Stdev(i,ExtFlyBuffer,Ext20MaBuffer,20);
      ExtUpperBandBuffer[i] = Ext20MaBuffer[i] + ExtStdevBuffer[i];
      ExtLowerBandBuffer[i] = Ext20MaBuffer[i] - ExtStdevBuffer[i];
      
    }
      
   return(rates_total);
//--- return value of prev_calculated for next call  
  }
  
//+------------------------------------------------------------------+

//--- Functions

double flyPrice(int k) {
   
   double flyPrice = (iClose("EURGBP", 0, k)-iClose("EURUSD", 0, k))-(iClose("EURUSD", 0, i)-iClose("GBPUSD", 0, k));
   
   return(flyPrice);



}

double MA(int m, int period1) {
   double sum1 = 0;
   double ma1;
   for(x=m; x<m+period1; x++) {
            sum1 = sum1 + flyPrice(x);
         }

   ma1 = sum1/period1; // Sum of prices divided number of bars gives us the SMA on closing price 
   return(ma1);        
   
}

double Stdev(int pos, double &price[], double &MA[], int period) {

   double StdevTemp=0.0;
   
   for (y=pos; y<pos+period; y++) {
      StdevTemp +=MathPow(price[pos]-MA[pos],2);
      StdevTemp = MathSqrt(StdevTemp/period);
   }
   
   return(StdevTemp);
}



Documentation on MQL5: Standard Constants, Enumerations and Structures / Objects Constants / Object Types
Documentation on MQL5: Standard Constants, Enumerations and Structures / Objects Constants / Object Types
  • www.mql5.com
Standard Constants, Enumerations and Structures / Objects Constants / Object Types - Reference on algorithmic/automated trading language for MetaTrader 5
 

Probably here:

   for (y=pos; y<pos+period; y++) {
      StdevTemp +=MathPow(price[y]-MA[y],2);
      StdevTemp = MathSqrt(StdevTemp/period);
 
Ernst Van Der Merwe:

Probably here:


yes you are right :)


problem solved


thank you again

 
Ernst Van Der Merwe:

Probably here:


Hey, sorry to bother you once more but could you possibly take another look at this code for me please?

I wrote another code and followed your previous advice as well but seem to be getting array out of range error again :(

//+------------------------------------------------------------------+
//|                                         Normalised Fly Price.mq4 |
//|                                                   Hyun soo Hwang |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Hyun soo Hwang"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window

#property indicator_level1     2
#property indicator_level2     1.5
#property indicator_level2     0
#property indicator_level3     -1.5
#property indicator_level4     -2.0

#property indicator_buffers 2
#property indicator_color1 Black
#property indicator_color2 Red

//--- Buffers
double ExtNormalised[];
double ExtNormalisedMA[];
double ExtFlyBuffer[];
double ExtMABuffer[];
double ExtStdevBuffer[];

//--- variables
int limit, i, x, y;
double total;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   IndicatorBuffers(5);
   
   SetIndexBuffer(0, ExtNormalised);
   SetIndexStyle(0, DRAW_LINE, STYLE_SOLID, 1);
   SetIndexLabel(0, "Normalised");
   
   SetIndexBuffer(1, ExtNormalisedMA);
   SetIndexStyle(1, DRAW_LINE, STYLE_DOT, 1);
   SetIndexLabel(1, "MA");
   
   SetIndexBuffer(2, ExtFlyBuffer);
   SetIndexBuffer(3, ExtMABuffer);
   SetIndexBuffer(4, ExtStdevBuffer);
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {

//--- Find number of bars to fill (aka find Limit)
   //int counted_bars=IndicatorCounted(); // IndicatorCounted returns number of bars not changed since the indicator had been launched last
   if(rates_total<20 || prev_calculated<0) return(0); // To check for errors
   //if(counted_bars>0) counted_bars--; // Minus 1 so as to always recount the last bar. Last bar may be formed incompletely

   limit=(prev_calculated==0)?rates_total-1:rates_total-prev_calculated; // Bars represent number of bars in the chart

//--- Main Calculation 
   for(i=limit; i>=0 && !_StopFlag; i--) {
   
      ///--- Fly price
      ExtFlyBuffer[i] = flyPrice(i);
      
      //--- Moving average
      ExtMABuffer[i] = MA(i, 20, ExtFlyBuffer);
      
      //--- Standard deviation
      ExtStdevBuffer[i] = Stdev(i, ExtFlyBuffer, ExtMABuffer, 20);
      
      //--- Normalised fly price
      ExtNormalised[i] = (ExtFlyBuffer[i]-ExtMABuffer[i])/ExtStdevBuffer[i];
      
      //-- Moving average on Normalised price
      ExtNormalisedMA[i] = MA(i, 20, ExtNormalised);
   }
   
//--- return value of prev_calculated for next call
   return(rates_total);
 }
//+------------------------------------------------------------------+

//--- Functions

double flyPrice(int k) {
   
   double flyPrice = (iClose("EURGBP", 0, k)-iClose("EURUSD", 0, k))-(iClose("EURUSD", 0, i)-iClose("GBPUSD", 0, k));
   
   return(flyPrice);

}

double MA(int m, int period1, double &array[]) {
   double sum1 = 0;
   double ma1;
   for(x=m; x<m+period1; x++) {
            sum1 = sum1 + array[x];
         }

   ma1 = sum1/period1; // Sum of prices divided number of bars gives us the SMA on closing price 
   return(ma1);        
   
}

double Stdev(int pos, double &price[], double &MA[], int period) {

   double StdevTemp =0.0;
   
   for (y=pos; y<pos+period; y++) {
      StdevTemp +=MathPow(price[pos]-MA[pos],2);    
   }
   StdevTemp = MathSqrt(StdevTemp/period);
   
   return(StdevTemp);
}
 
  1. double flyPrice(int k) {
       double flyPrice = (iClose("EURGBP", 0, k)-iClose("EURUSD", 0, k))-(iClose("EURUSD", 0, i)-iClose("GBPUSD", 0, k));
    Don't post code that does not compile!
  2. Do not assume non-chart indexes match. Always use iBarShift. Don't mix apples and oranges.
  3. You must make sure non-chart history has been downloaded. History data and error 4066 - MQL4 forum
    int OnCalculate( ...){
       if(!download_history(PERIOD_CURRENT, "EURGBP")
       || !download_history(PERIOD_CURRENT, "EURUSD")
       :
       ) return prev_calculate; // Wait for other charts to download.

  4.    limit=(prev_calculated==0)?rates_total-1:rates_total-prev_calculated; // Bars represent number of bars in the chart
       for(i=limit; i>=0 && !_StopFlag; i--) {      
          ExtMABuffer[i] = MA(i, 20, ExtFlyBuffer);
          ExtStdevBuffer[i] = Stdev(i, ExtFlyBuffer, ExtMABuffer, 20);
          ExtNormalised[i] = (ExtFlyBuffer[i]-ExtMABuffer[i])/ExtStdevBuffer[i];
          ExtNormalisedMA[i] = MA(i, 20, ExtNormalised);
    Your look back of price is zero. Your MA looks back 20. Your look back for STD is 20 plus MA look back. Your look back for normalized is maximum of price, MA, and STD. Look back for normalizedMA is normalized plus 20. Do your lookbacks correctly. You need four separate loops with separate starting indexes.
    • You look at limit - 20 thus array exceeded.
    • If you used zero instead of the default for EMPTY_VALUE, you would get divide by zero.
    • Your lines for the first 59 bars are bogus.
 
Hyun Hwang:


Hey, sorry to bother you once more but could you possibly take another look at this code for me please?

I wrote another code and followed your previous advice as well but seem to be getting array out of range error again :(

You stdDev function should not take two arrays, the MA value should be a single double and passed in as ExtMaBuffer[I] from the calling method

 
James Cater:

You stdDev function should not take two arrays, the MA value should be a single double and passed in as ExtMaBuffer[I] from the calling method


Thank you for that I mended it :)
 
whroeder1:
  1. Don't post code that does not compile!
  2. Do not assume non-chart indexes match. Always use iBarShift. Don't mix apples and oranges.
  3. You must make sure non-chart history has been downloaded. History data and error 4066 - MQL4 forum
  4. Your look back of price is zero. Your MA looks back 20. Your look back for STD is 20 plus MA look back. Your look back for normalized is maximum of price, MA, and STD. Look back for normalizedMA is normalized plus 20. Do your lookbacks correctly. You need four separate loops with separate starting indexes.
    • You look at limit - 20 thus array exceeded.
    • If you used zero instead of the default for EMPTY_VALUE, you would get divide by zero.
    • Your lines for the first 59 bars are bogus.


Thank you so much for your reply.


I am a total beginner at coding and I tried to take some time to go through your reply but I am still not getting it :(


Please excuse me if I am asking something too obvious:


1.  this part solved

2. I don't understand why I would need to work out the index of the bar using ibarshift when I already know I am going to use i as input within the for loop. 


for(i=limit; i>=0 && !_StopFlag; i--) {
   
      ///--- Fly price
      ExtFlyBuffer[i] = flyPrice(i);
      
      //--- Moving average
      ExtMABuffer[i] = MA(i, 20, ExtFlyBuffer);
      
      //--- Standard deviation
      ExtStdevBuffer[i] = Stdev(i, ExtFlyBuffer, ExtMABuffer[i], 20);
      
      //--- Normalised fly price
      ExtNormalised[i] = (ExtFlyBuffer[i]-ExtMABuffer[i])/ExtStdevBuffer[i];
      
      //-- Moving average on Normalised price
      ExtNormalisedMA[i] = MA(i, 20, ExtNormalised);
   }

3. 

I think the concept of lookback is rather confusing to me at the moment. Are you telling me that because the lookbacks aren't done properly so the code isn't computing the correct value for each buffer at the moment? It does compile and graphs everything but normalised doesn't seem right 



Could you please give me some more guidance on how to fix the main calculations please? I read your post on lookback but I am still not getting it :(


Thank you. Much appreciated

 
Hyun Hwang:

1.  this part solved

2. I don't understand why I would need to work out the index of the bar using ibarshift when I already know I am going to use i as input within the for loop. 

3.  I think the concept of lookback is rather confusing to me at the moment. Are you telling me that because the lookbacks aren't done properly so the code isn't computing the correct value for each buffer at the moment? It does compile and graphs everything but normalised doesn't seem right  Could you please give me some more guidance on how to fix the main calculations please? I read your post on lookback but I am still not getting it :(

  1. .
  2. double flyPrice = (iClose("EURGBP", 0, k)-iClose("EURUSD", 0, k))-(iClose("EURUSD", 0, i)-iClose("GBPUSD", 0, k));
    When you compute this, don't you want to use the value of the bars with the same time? You are assuming that iTime("...",0, k) (the other pairs) is the same as Time[k] (the chart.) Not necessarily so. New bar on one chart doesn't mean Anything changes on other pairs.
  3.    limit=(prev_calculated==0)?rates_total-1:rates_total-prev_calculated; // Bars represent number of bars in the chart
       for(i=limit; i>=0 && !_StopFlag; i--) {      
          ExtMABuffer[i] = MA(i, 20, ExtFlyBuffer);
          ExtStdevBuffer[i] = Stdev(i, ExtFlyBuffer, ExtMABuffer, 20);
    
    How can you compute a 20 period moving average when you don't have that many bars? You start at rates_total-1 (the oldest bar) and try to look back 20 bars. How can you compute a 20 period standard deviation, until you have 20 moving average values? Etc.
Reason: