Array out of range in Custom Function

 

Hi All,

Can someone point me to the error in the array, please?

Not sure why i keep getting the array out of range on line (163,12).

Thank you.

Regards,

John

//+------------------------------------------------------------------+
//|                                               Entry_Template.mq5 |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers   11
#property indicator_plots     3
//--- plot Buy Entry
#property indicator_label1 "Buy Entry"
#property indicator_type1  DRAW_ARROW
#property indicator_color1 clrSteelBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- plot Sell Entry
#property indicator_label2 "Sell Entry"
#property indicator_type2  DRAW_ARROW
#property indicator_color2 clrGoldenrod
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//--- plot 200 MA
#property indicator_label3 "200 MA"
#property indicator_type3  DRAW_COLOR_LINE
#property indicator_color3 clrGreen,clrRed
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1
//--- input parameters
input int                  inpPeriod = 9;
input ENUM_APPLIED_PRICE   inpPrice = PRICE_MEDIAN;
//--- indicator buffers
double   BuyEntryBuffer[];
double   SellEntryBuffer[];
double   MA200Buffer[],MA200BufferC[];
double   val[];
//---  Fisher Buffer
double priceft[],fb[],fc[],f1[],v1[];
//--- indicator handle
int      handle_MA200;
//---
int      bars_calculated   =  0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,BuyEntryBuffer,INDICATOR_DATA);
   PlotIndexSetInteger(0,PLOT_ARROW,159);
   PlotIndexSetInteger(0,PLOT_ARROW_SHIFT,10);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
   
   SetIndexBuffer(1,SellEntryBuffer,INDICATOR_DATA);
   PlotIndexSetInteger(1,PLOT_ARROW,159);
   PlotIndexSetInteger(1,PLOT_ARROW_SHIFT,-10);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
   
   SetIndexBuffer(2,MA200Buffer,INDICATOR_DATA);
   SetIndexBuffer(3,MA200BufferC,INDICATOR_COLOR_INDEX);
//--- 
   handle_MA200=iMA(Symbol(),Period(),200,0,MODE_SMMA,PRICE_CLOSE);
   if(handle_MA200==INVALID_HANDLE)
   {
      PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      return(INIT_SUCCEEDED);
   }   
//---
   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[])
  {
//---
   if(rates_total<200)
      return(0);
      
   int values_to_copy;
   int calculated=BarsCalculated(handle_MA200);
   if(calculated<=0){
      PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
      return(0);
   }
   if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1){
      if(calculated>rates_total)
         values_to_copy=rates_total;
      else
         values_to_copy=calculated;
   }
   else{
      values_to_copy=(rates_total-prev_calculated)+1;
   }
//---
   if(!FillArrayFromBufferiMA(MA200Buffer,0,handle_MA200,values_to_copy))
      return(0);   
//---
   bars_calculated=calculated;
   int limit=prev_calculated-1;
   if(prev_calculated==0){
      for(int i=0; i<200; i++)
         {
            BuyEntryBuffer[i]=0;
            SellEntryBuffer[i]=0;
         }
      limit=200+1;
   }
   for(int i=limit;i<rates_total;i++)
   {
      MA200BufferC[i] = MA200BufferC[i-1];
      if(MA200Buffer[i]>MA200Buffer[i-1])MA200BufferC[i] = 0;
      if(MA200Buffer[i]<MA200Buffer[i-1])MA200BufferC[i] = 1;
      
      val[i] = FisherTransform(open,high,low,close,i,rates_total);
         if(val[i]>val[i-1]){
            BuyEntryBuffer[i] = low[i];
         }
         if(val[i]<val[i-1]){
            SellEntryBuffer[i] = high[i];
         }
   
   }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Filling indicator buffers from the MA indicator                  |
//+------------------------------------------------------------------+
bool FillArrayFromBufferiMA(double &values[],   // indicator buffer of Moving Average values
                            int shift,          // shift
                            int ind_handle,     // handle of the iMA indicator
                            int amount          // number of copied values
                           )
   {
      ResetLastError();
      if(CopyBuffer(ind_handle,0,shift,amount,values)<0)
      {
         PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
         return(false);
      }
      return(true);
   }
//+------------------------------------------------------------------+
//| Fisher Transform                                                 |
//+------------------------------------------------------------------+
double FisherTransform(const double& open[],const double& high[],const double& low[],const double& close[] , int shift, int bars)
{   
   int start = shift>inpPeriod?shift-inpPeriod+1:0;
   priceft[shift] = getPrice(inpPrice,open,close,high,low,shift,bars);
   int mx = ArrayMaximum(priceft,start,inpPeriod);
   int mn = ArrayMinimum(priceft,start,inpPeriod); 
   
   if (mx == -1 || mn == -1) return(0);
   
   if(priceft[mx] != priceft[mn])
      v1[shift] = 0.33*2.0*((priceft[shift] - priceft[mn])/(priceft[mx] - priceft[mn]) - 0.5) + 0.667 * v1[shift - 1];
   else v1[shift] = 0;
   v1[shift] = MathMax(MathMin(v1[shift], 0.999), -0.999);
   
   double ft = ZerroIfEmpty(fb[shift - 1]);
   fb[shift] = 0.5 * MathLog((1 + v1[shift])/(1 - v1[shift])) + 0.5 * ft;
   
   return(fb[shift]);
}
//+------------------------------------------------------------------+
//| ZeroIfEmpty                                                      |
//+------------------------------------------------------------------+
double ZerroIfEmpty(double value) {
if (value >= EMPTY_VALUE || value <= -EMPTY_VALUE) return 0.0;
return value;
}
//+------------------------------------------------------------------+
//| Get Price                                                        |
//+------------------------------------------------------------------+
double getPrice(ENUM_APPLIED_PRICE tprice,const double &open[],const double &close[],const double &high[],const double &low[],int i,int _bars)
  {
   if(i>=0)
      switch(tprice)
        {
         case PRICE_CLOSE:     return(close[i]);
         case PRICE_OPEN:      return(open[i]);
         case PRICE_HIGH:      return(high[i]);
         case PRICE_LOW:       return(low[i]);
         case PRICE_MEDIAN:    return((high[i]+low[i])/2.0);
         case PRICE_TYPICAL:   return((high[i]+low[i]+close[i])/3.0);
         case PRICE_WEIGHTED:  return((high[i]+low[i]+close[i]+close[i])/4.0);
        }
   return(0);
  }   
 
John.Doe:

Hi All,

Can someone point me to the error in the array, please?

Not sure why i keep getting the array out of range on line (163,12).

Thank you.

Regards,

John

Do you expect us to count down to line 163??

 

Hi Keith,


Apologies, not sure how to add that counter thing at the side.

 
John.Doe: Can someone point me to the error in the array, please? Not sure why i keep getting the array out of range on line (163,12).

You declare "priceft[]" as an dynamic array (empty), but you don't assign it as an Indicator buffer, nor do you ever re-size it.

So, it is always empty, with no elements, and therefore, anything you try do with it will always give you a "array out of range" error.

double priceft[],fb[],fc[],f1[],v1[];

...

priceft[shift] = getPrice(inpPrice,open,close,high,low,shift,bars);

The same probably holds true for some of your other dynamic arrays.

 

hey Fernando,

Solved it.

Forgot my SetIndexBuffers.

Thank you Fernando and Keith.

Regards,

John

 
John.Doe #: Solved it.Forgot my SetIndexBuffers.Thank you Fernando and Keith.
You are welcome!
 
John.Doe #:

Hi Keith,


Apologies, not sure how to add that counter thing at the side.

You can use the highlighter in future. Then it is easy to find.