MQL5 MTF indicator returns error 4806

 

Hello developers

i am trying to make a multi timeframe fractal indicator that reads fractals from higher timeframe and draws them as support and resistance lines in lower timeframes.

but when testing it in strategy tester it returns error 4806, failure in reading data from indicator handle, very common issue in multi timeframe indicators, despite i found out it should be something about the bars which needed to be calculated but i couldn't fix the code

i searched a lot and read many topics here but i couldn't find the code solution!

the code is:

// Indicator Buffer Settings
#property indicator_chart_window
#property indicator_buffers   4                 // How many data buffers are we using
#property indicator_plots     2                 // How many indicators are being drawn on screen

#property indicator_label1    "Support"
#property indicator_type1     DRAW_ARROW
#property indicator_style1    STYLE_SOLID
#property indicator_color1    clrMagenta
#property indicator_width1    1

#property indicator_label2    "Resistance"
#property indicator_type2     DRAW_ARROW
#property indicator_style2    STYLE_SOLID
#property indicator_color2    clrLime
#property indicator_width2    1

// Indicator Input Parameters
input ENUM_TIMEFRAMES      TimeFrame                  =  PERIOD_CURRENT;                     // Indicator Timeframe

// Indicator Variables
string   IndName              =  "GGP S/R MTF";
int      PeriodShift;

// Indicator Buffers
double   Support[];
double   Resistance[];

// Sub indicator buffers and handles 
double   FractalUpBuffer[];            // Dynamic arrays to hold the Fractal up values for each bars
double   FractalDownBuffer[];          // Dynamic arrays to hold the Fractal down values for each bars
int      FractalHandle;                // Handle for Fractal Indicator

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   // Set indicator name
   IndicatorSetString(INDICATOR_SHORTNAME, IndName);

   // Set indicator digits
   IndicatorSetInteger(INDICATOR_DIGITS, (int) SymbolInfoInteger(Symbol(), SYMBOL_DIGITS));

   // Indicator buffers mapping
   int   bufferIndex    =  0;
   SetIndexBuffer(bufferIndex, Support, INDICATOR_DATA);
   PlotIndexSetInteger(bufferIndex, PLOT_DRAW_BEGIN, PeriodShift);
   PlotIndexSetInteger(bufferIndex, PLOT_ARROW, 159);

   bufferIndex++;
   SetIndexBuffer(bufferIndex, Resistance, INDICATOR_DATA);
   PlotIndexSetInteger(bufferIndex, PLOT_DRAW_BEGIN, PeriodShift);
   PlotIndexSetInteger(bufferIndex, PLOT_ARROW, 159);

   // Preparing Buffers
   ArraySetAsSeries(Support, true);
   ArraySetAsSeries(Resistance, true);

   ArrayInitialize(Support, EMPTY_VALUE);
   ArrayInitialize(Resistance, EMPTY_VALUE);

   // Get handle for Fractal indicator
   FractalHandle     =  iFractals(_Symbol, TimeFrame);
   // What if handle returns Invalid Handle
   if(FractalHandle < 0)
      {
       Alert("Error Creating Handles for Fractals indicator - error: ", GetLastError(), "!!");
       return(-1);
      }

   // Additional Buffers for Calculations
   bufferIndex++;
   SetIndexBuffer(bufferIndex, FractalUpBuffer, INDICATOR_DATA);

   bufferIndex++;
   SetIndexBuffer(bufferIndex, FractalDownBuffer, INDICATOR_DATA);

   // Preparing sub indicator buffers
   ArraySetAsSeries(FractalUpBuffer, true);
   ArraySetAsSeries(FractalDownBuffer, true);

   ArrayInitialize(FractalUpBuffer, EMPTY_VALUE);
   ArrayInitialize(FractalDownBuffer, EMPTY_VALUE);

   PeriodShift       =  PeriodSeconds(TimeFrame)/ PeriodSeconds(PERIOD_CURRENT);
   
//---
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   IndicatorRelease(FractalHandle);
   ChartRedraw(0);   
  }

//+------------------------------------------------------------------+
//| 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[])
  {
   // Do calculations on new bar only
   if(rates_total == prev_calculated)
      return(rates_total);

   // Checks the forced shutdown of the MetaTrader program
   if(IsStopped())
      return(0);

   // Check all the indicators bars have been calculated
   if(BarsCalculated(FractalHandle) < iBars(_Symbol, TimeFrame))
      return(0);

   // Finding how many bars needed to be calculated each time in order to increase the indicator speed
   int Limit = 0;
   if(prev_calculated > rates_total || prev_calculated <= 0)
     {
      Limit = rates_total- PeriodShift- 1;
      
      ArrayInitialize(Support, EMPTY_VALUE);
      ArrayInitialize(Resistance, EMPTY_VALUE);
      ArrayInitialize(FractalUpBuffer, EMPTY_VALUE);
      ArrayInitialize(FractalDownBuffer, EMPTY_VALUE);
     }

   else
     {
      Limit = rates_total- prev_calculated- PeriodShift- 1;
      
      // Making the indicator to calculate for the 10 last bars
      if(Limit <= 1)
         Limit = 10;
     }

   // Indicator Calculations
   for(int i=Limit; i>=0; i--)
     {
      datetime    barTime  =  iTime(_Symbol, _Period, i);
      int         barMTF   =  iBarShift(_Symbol, TimeFrame, barTime, false);

      if(ShiftUpFractal(barMTF, Limit) > 0 && ShiftUpFractal(barMTF, Limit) != EMPTY_VALUE)
         Resistance[i]     =  ShiftUpFractal(barMTF, Limit);
      else
         Resistance[i]     =  Resistance[i+1];
      
      if(ShiftDownFractal(barMTF, Limit) > 0 && ShiftDownFractal(barMTF, Limit) != EMPTY_VALUE)
         Support[i]        =  ShiftDownFractal(barMTF, Limit);
      else
         Support[i]        =  Support[i+1];
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }

//+------------------------------------------------------------------+
//| Up Fractal Values                                                |
//+------------------------------------------------------------------+
double ShiftUpFractal(int bar, int count)
   {
    // Get Fractal Data from Handle
    int upCount      =  CopyBuffer(FractalHandle, 0, bar, count, FractalUpBuffer);
    if(upCount < 0)
      {
       int upErr     =  GetLastError();
       Print("Reading data from up Fractal indicator handle failed!! Error: ", upErr);
       return(-1);
      }

    return(FractalUpBuffer[bar]);    
   }

//+------------------------------------------------------------------+
//| Down Fractal Values                                              |
//+------------------------------------------------------------------+
double ShiftDownFractal(int bar, int count)
   {
    // Get Fractal Data from Handle
    int downCount    =  CopyBuffer(FractalHandle, 1, bar, count, FractalDownBuffer);
    if(downCount < 0)
      {
       int downErr   =  GetLastError();
       Print("Reading data from low Fractal indicator handle failed!! Error: ", downErr);
       return(-1);
      }
   
    return(FractalDownBuffer[bar]);    
   }

Thanks in advance.

 
It's working on my side. Both backtest and live. Although a bit slow when loading.
 
Yashar Seyyedin #:
It's working on my side. Both backtest and live. Although a bit slow when loading.
Thanks for replying Yashar
I changed the code and it is working properly and fast now, i will share the code soon for your review to make it performs even better and for others if they face this issue 
 
Mohammadmahmood Pirayeh #:
better

Happy to hear that. Thanks.