Timeseries/copyrates issue, mtf, weekend, no new tick

 

Please correct me if anything I've said is off, if I'm missing something I need to know.

Context: Timeseries and copyrate functions are asynchronous, so they can't return the requested data if it isn't ready yet, and instead return 0 or -1 and generate an error code like 4401-ERR_HISTORY_NOT_FOUND. But having requested the data, the building of the requried mtf/cachefolder-hc files has begun. Documentation advises to ask for the data again, as after some short time it should be ready.

Complication: If a user expects the mtf data to just appear straight away or within a couple of seconds, or without having to do anything manually like right-click-refresh or change tfs, or without having to wait for the next tick, then the documentation provides a way to programatically reload the indicator via ChartSetSymbolPeriod(0,NULL,0); to reload the chart and reinitialize all indicators. This is what I've been using and has been suggested on https://www.mql5.com/en/forum/315369.

Problem: A user reported to me a flashing issue, and I can replicate the issue, it seems the solution of ChartSetSymbolPeriod isn't working anymore, or we're both doing something wrong. iHigh and CopyHigh, aren't working or being accessed like they normally do, and this mtf issue is also present on mtf indicator handles.

Investigation: if I open a h1 chart that doesn't have any higher mtf data requested yet, and load this test indicator:

#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots 0

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+

int OnInit()
{
   return(INIT_SUCCEEDED);
}


//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+

double ihigh_val;
double chigh_arr[];
int chigh_count;
int counter;

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(prev_calculated<0)return(-1);
   if(IsStopped())return(-1);

   ResetLastError();
   
   ihigh_val = iHigh(_Symbol,PERIOD_H4,0);
   chigh_count = CopyHigh(_Symbol,PERIOD_H4,0,1,chigh_arr);
   
   string copyrates_text = chigh_count<0 ? "failed" : DoubleToString(chigh_arr[0],_Digits);
   
   Print(   "Counter=",counter,
            "___ihigh_val=",DoubleToString(ihigh_val,_Digits),
            "___copyrates=",copyrates_text,
            "___Error=",GetLastError(),
            "___Ratestotal=",rates_total,
            "___Deinit=",GlobalVariableGet("random")
         );   
   
   if(ihigh_val==0){
      EventSetTimer(5);
      //ChartSetSymbolPeriod(0,NULL,0);
      //return(0);
   }
   
   
   return(rates_total);
}
//+------------------------------------------------------------------+
void OnTimer()
{
   counter++;
   EventKillTimer();
   ChartSetSymbolPeriod(0,NULL,0);
   
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

void OnDeinit(const int reason)
{
   // 0 = REASON_PROGRAM
   // 1 = REASON_REMOVE 
   // 2 = REASON_RECOMPILE
   // 3 = REASON_CHARTCHANGE 
   // 4 = REASON_CHARTCLOSE 
   // 5 = REASON_PARAMETERS 
   // 6 = REASON_ACCOUNT 
   // 7 = REASON_TEMPLATE 
   // 8 = REASON_INITFAILED 
   // 9 = REASON_CLOSE 

   if(reason!=1)GlobalVariableSet("random",reason+100);
   else GlobalVariableDel("random");
}

generates the following printouts:

Ideally these prinouts would be limited to 1 or 2 printouts, but because the timeseries access, or accessing the values from timeseries access, aren't working like they usually are, the prinouts don't stop, the indicator keeps reloading indefinitely.

I moved the ChartSetSymPeriod() out of OnCalculcate and into OnTimer, to slow down the reloading, else the counter would quickly reach double and tripple digits.

The second call of OnCalcuate after ChartSetSymPeriod() is clearing out the values that iHigh and CopyHigh would have had. The global counter is not reinitializing to 0 on ChartSetSymPeriod() , it does however on recompiling and changing chart tf.

Anyone else able to replicate this? or know another workaround? or what's going on?

[MT5] MTF Indicator Trick on weekends.
[MT5] MTF Indicator Trick on weekends.
  • 2019.06.09
  • www.mql5.com
The multi-timeframe indicator on MT5 never works on weekends...
 

Update: Issue seems to have resolved itself. Running the same test indicator, on symbols without previously called mtf data, seems to work as expected now. Still no idea what the original issue was, turning the terminal+editor off and on again didn't change anything, and the issue was originally reported to me by someone else.

Running the same test indicator gives the following printouts

- first call is empty, expected

- second call gets the requested data, expected

- no third call needed, previous issue is gone