multidimensional array: Out of Range

 

Dear,

I would like to contrast DIs (ADX) with different averaging time frame , so I created a custom Indicator using the basics of ADX Wilder Moving from PD and ND along with TR to PDS, NDS, PDI and NDI with different averaging number (1,2, 3, to 14). I would like generate a matrix of PDI with in row time and columns 14 PDIs with each different averaging number. I guess that this can be handled with array computation. I tried to do (code below) but i get the message out of range. Please, I appreciate your help and comments:

//--- input parameters
input int InpNberPeriod=14; // Period
int filePtr; 
//---- buffers
double    ExtTBuffer[];
double    ExtPDBuffer[];
double    ExtNDBuffer[];
double    ExtTRBuffer[];
double    PDI[][14];
double    NDI[][14];
double    PDS[][14];
double    NDS[][14];
double    ATR[][14];
//--- global variable
int       ExtNberPeriod;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- check for input parameters
   if(InpNberPeriod>=100 || InpNberPeriod<=0)
     {
      ExtNberPeriod=14;
      printf("Incorrect value for input variable InpNberPeriod=%d. Indicator will use value=%d for calculations.",InpNberPeriod,ExtNberPeriod);
     }
   else ExtNberPeriod=InpNberPeriod;
   
//---- indicator buffers
  
   SetIndexBuffer(0,ExtPDBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(1,ExtNDBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,ExtTRBuffer,INDICATOR_CALCULATIONS);

//--- set draw begin
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtNberPeriod<<1);
   PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,ExtNberPeriod+1);
   PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,ExtNberPeriod+1);
//--- indicator short name
   string short_name="ADX("+string(ExtNberPeriod)+")";
   IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- change 1-st index label
   PlotIndexSetString(0,PLOT_LABEL,short_name);
//--- indicator digits
   IndicatorSetInteger(INDICATOR_DIGITS,2);
//---- end of initialization function
filePtr =FileOpen("FileOutput.csv",FILE_WRITE|FILE_CSV);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//--- checking for bars count
   if(rates_total<ExtNberPeriod)
      return(0);
//--- detect start position
   int start;
   if(prev_calculated>1) start=prev_calculated-1;
   else
     {
      start=1;
      for(int i=0;i<ExtNberPeriod;i++)
        {
         ExtTBuffer[i]=0;
         ExtPDBuffer[i]=0;
         ExtNDBuffer[i]=0;
         ExtTRBuffer[i]=0;
        }
     }
//--- main cycle
   for(int i=start;i<rates_total && !IsStopped();i++)
     {  //--- get some data
      double Hi    =high[i];
      double prevHi=high[i-1];
      double Lo    =low[i];
      double prevLo=low[i-1];
      double prevCl=close[i-1];
      //--- fill main positive and main negative buffers
      double dTmpP=Hi-prevHi;
      double dTmpN=prevLo-Lo;
      if(dTmpP<0.0) dTmpP=0.0;
      if(dTmpN<0.0) dTmpN=0.0;
      if(dTmpN==dTmpP)
        {
         dTmpN=0.0;
         dTmpP=0.0;
        }
      else
        {
         if(dTmpP<dTmpN) dTmpP=0.0;
         else            dTmpN=0.0;
        }
      ExtPDBuffer[i]=dTmpP;
      ExtNDBuffer[i]=dTmpN;
      double tr=MathMax(MathMax(MathAbs(Hi-Lo),MathAbs(Hi-prevCl)),MathAbs(Lo-prevCl));
      ExtTRBuffer[i]=tr;
      
      for(int j=0;j<14;j++){
      if(i<ExtNberPeriod)
        {
        
       
         ATR[i][j]=0.0;
         PDS[i][j]=0.0;
         NDS[i][j]=0.0;
        
        }
      else
        {
         ATR[i][j]=SimpleMA(i,j+1,ExtTRBuffer);
         PDS[i][j]=SimpleMA(i,j+1,ExtPDBuffer);
         NDS[i][j]=SimpleMA(i,j+1,ExtNDBuffer);
          }
          if(ATR[i][j]!=0.0)
        {
         PDI[i][j]=100.0*PDS[i][j]/ATR[i][j];
         NDI[i][j]=100.0*NDS[i][j]/ATR[i][j];
    
         }
      else
        {
         PDI[i][j]=0.0;
         NDI[i][j]=0.0;
        }
           
    FileWrite(filePtr ,TimeToString(TimeCurrent(), TIME_DATE | TIME_MINUTES ),PDI[i][j]);
        }
    
        
        
 

  
     }
//---- OnCalculate done. Return new prev_calculated.
   return(rates_total);
  }

 
I have met similar problem as you did. Seems like accessing 2d array in `OnCalculate` would lead to `Index out of bound` error.
 
  1. use the debugger to check the index and the array size (of any dimension) before you access the array: https://www.mql5.com/en/articles/654
  2. use ArrayRange() to check the sizes of the dimensions.
Debugging MQL5 Programs
Debugging MQL5 Programs
  • www.mql5.com
This article is intended primarily for the programmers who have already learned the language but have not fully mastered the program development yet. It reveals some debugging techniques and presents a combined experience of the author and many other programmers.
 
You didn't set PDI, NDI, etc.. as buffers with SetIndexBuffer, just declaring a variable as x[] won't work because it is an empty array.