Why indicator dissapear when changing timeframe of the indicator?

 

I am currently using an indicator I found in the codebase.

When it loads in the chart it displays fine (Left figure), but when I change the TimeFrame, the indicator disappear (middle figure); when I add any other indicator ,the original indicator appears with the updated change (left figure).

Like if it fails to initiate after changing the TF.... is there a reason for this behavior?


AllAverages v4.9 MT5
AllAverages v4.9 MT5
  • www.mql5.com
One of the latest version of this indicator at the moment. Huge base of different modifications of moving averages, with multitimesframe function, sending signals to e-mail and push notifications.
 

I found that the problem is an error due to the fact that MQL5 does not wait for the data to download in the new TF, so one get ERROR 4806. The next time an indicator is loaded the data is ready, and that explains the behaviour of why the new TF indicator appears after another indicator is loaded.

2023.11.04 07:47:36.060 MA_MultiTF (EURUSD,M1)  Not All data of ExtHandle1 is calculated (-1bars ). Error4806

A suggested solution in this POST is to calculate the next bar in the next tick. The problem is that at that time one is already on the OnCalculate part of the indicator, so the handle is never created (This is why the indicator never appears), the question is then how can one trigger the OnInit again, if an error occurs in the OnCalculate?

Here is an example of classic MTF mean, that yields this error:

//+------------------------------------------------------------------+
//|                                                   MA_MultiTF.mq5 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//---- indicator settings
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  Blue
#property indicator_width1  1
//---- input parameters
input ENUM_TIMEFRAMES    tf              = 5;              // Time Frame 
input int                maPeriod        = 13;             // MA period
input int                Shift           = 0;              // Shift
input ENUM_MA_METHOD     InpMAMethod     = MODE_SMA;       // Moving average method
input ENUM_APPLIED_PRICE InpAppliedPrice = PRICE_CLOSE;    // Applied price
input bool               Interpolate     = true;
input  int               Bars_Calculated = 500;
//---- indicator buffers
double ExtMA[];
//---- handles for moving averages
int    MA_Handle;
//--- bars minimum for calculation
int    ExtBarsMinimum;
ENUM_TIMEFRAMES _tf;
int pf;
int draw_begin;
//--- we will keep the number of values in the Moving Average indicator 
int    bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   _tf=tf;
   ENUM_TIMEFRAMES timeframe;
   int draw_shift=Shift;// initial PLOT_SHIFT value
   draw_begin=maPeriod;// initial value PLOT_DRAW_BEGIN
//---
   timeframe=_Period;
   if(_tf<=timeframe)_tf=timeframe;// if the TF is less than or is equal to the current one, set it to PERIOD_CURRENT
   pf=(int)MathFloor(_tf/timeframe);// calculate coefficient for PLOT_DRAW_BEGIN, PLOT_SHIFT and the number of calculation bars.
   draw_begin=maPeriod*pf;// calculate PLOT_DRAW_BEGIN
   draw_shift=Shift*pf;// calculate PLOT_SHIFT
//---- indicator buffers mapping
   SetIndexBuffer(0,ExtMA,INDICATOR_DATA);
//---
   PlotIndexSetInteger(0,PLOT_SHIFT,draw_shift);                              //line shifts when drawing
   PlotIndexSetString(0,PLOT_LABEL,"MA("+string(tf)+" "+string(maPeriod)+")");//name for DataWindow
//---- Disabling drawing of empty indicator values
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
//--- get MA's handles
   MA_Handle=iMA(NULL,_tf,maPeriod,0,InpMAMethod,InpAppliedPrice);            //
   if(MA_Handle==INVALID_HANDLE)
     {
      Print("getting MA Handle is failed! Error",GetLastError());
      return(INIT_FAILED);
     }
//--- set accuracy
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- bars minimum for calculation
   ExtBarsMinimum=draw_begin+draw_shift;// calculate the minimum required number of bars for the calculation
//--- initialization done
   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[])
  {
//--- check for rates total
   if(rates_total<ExtBarsMinimum+pf)
      return(0); // not enough bars for calculation
   int limit,limit1;
   if(Bars_Calculated!=0)draw_begin=Bars(NULL,0)-Bars_Calculated;
//---
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,draw_begin+pf);                      //sets first bar from what index will be drawn
//--- apply timeseries indexing to array elements  
   ArraySetAsSeries(time,true);
   ArraySetAsSeries(ExtMA,true);
//--- not all data may be calculated
   int calculated=BarsCalculated(MA_Handle);
//---
   if(calculated<=0)
     {
      Print("Not All data of ExtHandle1 is calculated (",calculated,"bars ). Error",GetLastError());
      return(0);
     }
//--- detect start position
//--- calculations of the necessary amount of data to be copied
//--- and the 'limit' starting index for the bars recalculation loop
   if(prev_calculated>rates_total || prev_calculated<=0|| calculated!=bars_calculated)// checking for the first start of the indicator calculation
     {
      limit=rates_total-ExtBarsMinimum-1; // starting index for calculation of all bars
     }
   else
     {
      limit=(rates_total-prev_calculated)+pf+1; // starting index for calculation of new bars
     }
   if(Bars_Calculated!=0)   limit=MathMin(Bars_Calculated,limit);

//--- main cycle
   for(int i=limit;i>=0 && !IsStopped();i--)
     {
      int n;
      datetime t=time[i];
      ExtMA[i]=_CopyBuffer(MA_Handle,t);
      if(!Interpolate) continue;
      //---
      limit1=limit;
      if(limit==Bars_Calculated)limit1=limit-1;
      datetime times= _iTime(t);
      for(n = 1; i+n<limit1+1 && time[i+n]>= times; n++) continue;
      double factor=1.0/n;
      for(int k=1; k<n; k++)
      ExtMA[i+k]=k*factor*ExtMA[i+n]+(1.0-k*factor)*ExtMA[i];
     }
//---
   bars_calculated=calculated;
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
datetime _iTime(datetime start_time)
{
   if(start_time < 0) return(-1);
   datetime Arr[];
   if(CopyTime(NULL,_tf, start_time, 1, Arr)>0)
        return(Arr[0]);
   else return(-1);
}
//+--------- CopyBuffer MA Handle ----------------------------------+
double _CopyBuffer(int handle,datetime start_time)
  {
   double buf[];
   if(CopyBuffer(handle,0,start_time,1,buf)>0)
      return(buf[0]);

   return(EMPTY_VALUE);
  }
//+-------------------- END -----------------------------------------+
After working on this issue, I also found this POST , which claims to use a timer, but the error still persists
Error 4806 Requested data not found when CopyBuffer
Error 4806 Requested data not found when CopyBuffer
  • 2019.09.16
  • www.mql5.com
Hi Traders/Devs, I am trying to create quite a complex indicator that pulls data from the 28 major pairs and I keep getting error 4806 when I try t...
 
Because the terminal doesn't have the data. That's what I tried to explain to you in mp. The 4806 is quite difficult to get around, it's a matter of pre-treatment. 2 main solutions are possible. The metaquotes solution is to use a script that loads all the data before exploitation. A less recommended but which I think is simpler is to go through a "do nothing" type loop which makes you wait for everything to be loaded. I still have to test both solutions to see
 

Hi Gerard,

A suggested solution in this Post is to add a delay a then refresh the handle. I am trying this but have not fixed the problem.

[SOLVED] Indicators are not properly instantiated when called/created from an Indicator of different working time-frame. - How to fix bug in H1 Charting Indicator.
[SOLVED] Indicators are not properly instantiated when called/created from an Indicator of different working time-frame. - How to fix bug in H1 Charting Indicator.
  • 2017.01.30
  • www.mql5.com
Full indicator code: the only way to not receive an error is to launch this on h1 charts (same tf). Workaround: the workaround was to create the indicator in oninit() and set eventsetmillisecondtimer to 1ms
 

I found this POST, which appears to provide a good solution.


if (BarsCalculated(handlerMtf) < 0)
{
        PrintFormat("Data not found (Timeframe :: %s-%d) >>", GetLastError());
        ChartSetSymbolPeriod(0, NULL, 0);
        return 0;
}
Error 4806 while using CopyBuffer()
Error 4806 while using CopyBuffer()
  • 2018.06.17
  • www.mql5.com
Hi, I would like to just get the value of a custom indicator in an Expert Advisor, here is my code : Which give me : Is it the correct way to get a...
 
Camilo Mora #:

I found this POST, which appears to provide a good solution.


This code need to be placed on the onInit

if (BarsCalculated(handlerMtf) < 0)
{
        PrintFormat("Data not found (Timeframe :: %s-%d) >>", EnumToString(Period()), GetLastError());
        ChartSetSymbolPeriod(0, NULL, 0);
        return 0;
}
Reason: