array out of range why?

 

i am  trying to code the indicator Momentum, this Momentum Indicator isn´t the same as the Metatrader Momentum indicator.


//+------------------------------------------------------------------+
//|                                                          ADX.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "2009, MetaQuotes Software Corp."
#property link        "http://www.mql5.com"
#property description "Average Directional Movement Index"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  LightSeaGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
#property indicator_label1  "Momentum"

double Mom[];

input int InpMom = 20;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {

   SetIndexBuffer(0,Mom);
//--- indicator digits
   IndicatorSetInteger(INDICATOR_DIGITS,2);
//--- indicator short name
   string short_name="Mom("+string(InpMom)+")";
   IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- change 1-st index label
   PlotIndexSetString(0,PLOT_LABEL,short_name);
//---- end of initialization 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 &TickVolume[],
                const long &Volume[],
                const int &Spread[])
  {
//--- checking for bars count
   if(rates_total < InpMom)
     {
      return 0;
     }
//--- detect start position
   int start = prev_calculated - 1;
//--- main cycle
   for(int i=start;i < rates_total ;i++)
     {
      Mom[i] = Close[i] - Close[i-InpMom];
     }
//---- OnCalculate done. Return new prev_calculated.
   return(rates_total);
  }
//+------------------------------------------------------------------+

can somebody tell me why the error  "array out of range" print out every time i start the indicator;

 
Cypher Omikron:

i am  trying t code the indicator Momentum

Why? It is already on your PC: ..\MQL5\Indicators\Examples\Momentum.mq5

Bear in mind there's virtually nothing that hasn't already been programmed for MT4/MT5 and is ready for you - copy & paste the fastet from to code especially for beginners.

 
Carl Schreiber #:

Why? It is already on your PC: ..\MQL5\Indicators\Examples\Momentum.mq5

Bear in mind there's virtually nothing that hasn't already been programmed for MT4/MT5 and is ready for you - copy & paste the fastet from to code especially for beginners.

i´ve forgot to insert the code
 

because [i - 20] cannot be certain to exist at the start of the loop


this will stop the error from happening:


//+------------------------------------------------------------------+
//|                                                          ADX.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "2009, MetaQuotes Software Corp."
#property link        "http://www.mql5.com"
#property description "Average Directional Movement Index"

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrLightSeaGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
#property indicator_label1  "Momentum"


double Mom[];

input int InpMom = 20;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {

   SetIndexBuffer(0,Mom);
//--- indicator digits
   IndicatorSetInteger(INDICATOR_DIGITS,2);
//--- indicator short name
   string short_name="Mom("+string(InpMom)+")";
   IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- change 1-st index label
   PlotIndexSetString(0,PLOT_LABEL,short_name);
//---- end of initialization 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[])
{

//--- checking for bars count
   if(rates_total < InpMom)
     {
      return 0;
     }
//--- detect start position
   int start = prev_calculated;
//--- main cycle
   for(int i=start;i < rates_total;i++)
     {   
     
       if(i >= InpMom){
           Mom[i] = close[i] - close[i-InpMom];
       }
     }
     
     ArraySetAsSeries(Mom, true);
//---- OnCalculate done. Return new prev_calculated.
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
phade #:

because [i - 20] cannot be certain to exist at the start of the loop


this will stop the error from happening:


prev_calculated starts as zero as well... You need to account for that, too..

 
Dominik Christian Egert #:
prev_calculated starts as zero as well... You need to account for that, too..

that condition I added accounts for that, the code will work perfectly

if( i>0 && i>- InpMom) would just be adding extra check that doesn't need to be there in my humble opinion, because the condition isn't satisfied until i >= InpMom

 
phade #:

that condition I added accounts for that, the code will work perfectly

if( i>0 && i>- InpMom) would just be adding extra check that doesn't need to be there in my humble opinion, because the condition isn't satisfied until i >= InpMom

Right, I oversaw that check, because I would have expected it outside the for loop.

In fact having it outside is more efficient.
 

ok, you can do this also I guess:

int start = prev_calculated;

start = (start <= InpMom) ? InpMom : prev_calculated;
  
for(int i=start;i < rates_total;i++)
{   
    Mom[i] = close[i] - close[i-InpMom];
}