[MT5] MTF Indicator Trick on weekends.

 
The multi-timeframe indicator on MT5 never works on weekends.
On weekends,the market is closed and there is no tick events,there is awlway getting error 4806 ("Requested data not found") when you load a mtf indicator to a chart.

I found that if I load another indicator to another chart,the mtf indicator will get another call to OnCalculate(),and the mtf ind will work well.

So I did some tests to see how the mtf indicator works on weekends.

I prepared two indicators:
MA-MTF.mq5  --- this is a simple mtf ma indicator

test_event_trigger.mq5 --- this is an empty indicator which is used to generate "tick event" when it is loaded to a chart.

Note: 

If your MT5 has not enough local data ,you should disconnect the MT5 server to avoid the chart update which will call OnCalculate().

If you do testing is not at the weekend, you should disconnect the MT5 server.


MA-MTF.mq5 

//+------------------------------------------------------------------+
//|                                                       MA-MTF.mq5 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot MA
#property indicator_label1  "MA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

input int            InpPeriod=14;
input ENUM_TIMEFRAMES InpTimeframe=PERIOD_H4;

//--- indicator buffers
double         MABuffer[];

ENUM_TIMEFRAMES TimeFrame;

int handle=-1;
static int counter=0;
string indName;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,MABuffer,INDICATOR_DATA);
   ArraySetAsSeries(MABuffer,true);

   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);

   TimeFrame=InpTimeframe>Period() ? InpTimeframe : Period();
   handle=iMA(Symbol(),TimeFrame,InpPeriod,0,MODE_SMA,PRICE_OPEN);
   if(handle==-1)
     {
      Print("Create iMA handle failed. Error code:",GetLastError());
      return(INIT_FAILED);
     }

   string tfs=EnumToString(TimeFrame);
   indName=StringFormat("%s (%s, %d) ",MQLInfoString(MQL_PROGRAM_NAME),tfs,InpPeriod)+" ChartID="+(string)ChartID();
   Comment(indName);
//---
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason) {  Comment("");  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
   Print("indName=",indName,"  counter=",++counter,"  prev_calc=",prev_calculated);
   if(rates_total<=InpPeriod)return(0);

   ArraySetAsSeries(time,true);
   int maxBars=iBars(Symbol(),TimeFrame);
//---
   double tmp[1]={0};
   for(int i=0;i<1000 && i<rates_total;i++)
     {
      MABuffer[i]=0;
      int shift=iBarShift(Symbol(),TimeFrame,time[i]);
      if(shift>=maxBars-InpPeriod)break;
      if(CopyBuffer(handle,0,shift,1,tmp)==1)
        {
         MABuffer[i]=tmp[0];
        }
      else if(i<3)
        {
         Print("indName=",indName," i=",i,"  prev_calc=",prev_calculated,"   Error=",GetLastError());//...Error = 4806           
        }
     }

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


test_event_trigger.mq5

//+------------------------------------------------------------------+
//|                                           test_event_trigger.mq5 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
string indName;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   indName=MQLInfoString(MQL_PROGRAM_NAME);
   Comment(indName);
//---
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason) {  Comment("");  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---

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


//

Files:
 
//****
Test 1:  the two charts are both GBPUSD and M30, Chart A and Chart B

Step1: load the MA-MTF to the chart A, it does not work.
Step2: load test_event_trigger to the chart B, now the chart A gets "tick event" and it works well.

It was said that the chars with the same symbol and timeframe have the same thread.

So the "tick event" was sent to the thread,this is why the chart A gets "tick event" when I load an indicator to the chart B, 

Screenshot step1:



Screenshot step2:


.


 
//****
Test 2: the two charts are both GBPUSD and M30, Chart A and Chart B
Step1: load the MA-MTF to the chart A, it does not work.
Step2: load the MA-MTF to the chart B, now the chart A and  B both work.
In this test, the MA-MTF on chart A/B has the same inputs.

It seems there is a message queue... the chart A/B both get the same message.

Screenshot step1:


Screenshot step2:


.

 
//****
Test 3: the two charts are both GBPUSD and M30, Chart A and Chart B
Step1: load the MA-MTF to the chart A, it does not work.
Step2: load the MA-MTF to the chart B, now the chart A works well but the chart B does not work.
In this test, the MA-MTF on chart A/B has the different inputs.
On the chart A, the inpPeriods is 14
On the chart B, the inpPeriods is 20 and get an error 4806

It seems there is a message queue... 
Does only the chart A get the tick message ? 
or the tick message was sent to the chart A and B,but only the chart A responded to the message?

So usually the message includes the specific info. of the MA-MTF indicator(inputs info.) ?

Screenshot step1:



Screenshot step2:


.


 
//****
Test 4:  Chart A:GBPUSD,M30 and Chart B:GBPUSD,H1
Step1: load the MA-MTF to the chart A, it does not work.
Step2: load the MA-MTF to the chart B, now the chart A does not work yet, but the chart B works.
In this test, the MA-MTF on chart A/B has the same inputs( Period_H4,14)
The chart A and B are not in the same thread.

Only the chart B get the message.

Screenshot step1:




Screenshot step2:


.

 
Test 5:  Chart A:GBPUSD,M30 and Chart B:GBPUSD,H1
Step1: load the MA-MTF to the chart A, it does not work.
Step2: load the MA-MTF to the chart B, the chart A and B do not work.
In this test, the MA-MTF on chart A/B has the different inputs.
On chart A, the inpPeriods is 14 and get an error 4806
On chart B, the inpPeriods is 20 and get an error 4806

The chart A and B are not in the same thread.
The message queue for chart A needs a trigger to push the message to the chart A.
The message queue for chart B needs a trigger to push the message to the chart B.

...

Screenshot step1:



Screenshot step2:


.

 

I am confused, I can not draw a conclusion.

MTF coding is simple and easy on MT4, but its getting annoying on MT5.

If you want to MTF indicators on MT5 to work on weekends, you should do some extra job such as call Oncalculate() in OnTimer()...

Just share the info. in the forum.

 

Yes, it seems that MT5 has some stupid behaviour. I'm also struggling with the "weekend" problem.

I found that this code is problematic:

int maxBars=iBars(Symbol(),PERIOD_CURRENT);

It gives 0 to me when I'm switching between time frames.

When I'm switching between M1/M5/M15/M30/H1 it works well, but above H1 it doesnt work and gives 0 (although there are bars on the chart, the indicator cannot "see" them).

I have no idea. Extremely annoying.

I tried this example to update the bars and get the proper value, but no success.

 
Ziheng Zhuang: MTF coding is simple and easy on MT4, but its getting annoying on MT5.
On MT4: Unless the current chart is that specific pair/ TF referenced, you must handle 4066/4073 errors before accessing prices.
          Download history in MQL4 EA - Forex Calendar - MQL4 programming forum - Page 3 #26 № 4

The function linked to, opens a hidden chart for the symbol/TF in question (if not already open,) thus updating history, and temporarily placing the symbol on Market Watch (if not already there,) so SymbolInfoDouble(symbol, SYMBOL_BID) or MarketInfo(symbol, MODE_BID) don't also return zero the first call.

On MT5: Unless the chart is that specific pair/ TF, you must Synchronize the terminal Data from the Server.
          Is it mystical?! It is! - Withdraw - Technical Indicators - MQL5 programming forum
          Timeseries and Indicators Access / Data Access - Reference on algorithmic/automated trading language for MetaTrader 5
          Synchronize Server Data with Terminal Data - Symbols - General - MQL5 programming forum

 
Ziheng Zhuang:

I am confused, I can not draw a conclusion.

MTF coding is simple and easy on MT4, but its getting annoying on MT5.

If you want to MTF indicators on MT5 to work on weekends, you should do some extra job such as call Oncalculate() in OnTimer()...

Just share the info. in the forum.

You are right it's confusing.

However there is a simple solution, just refresh you chart (right-click on the chart -> Refresh). This can also be done by code using ChartSetSymbolPeriod(0,NULL,0), it will refresh all indicators on all charts using the given symbol. This will work well in most cases, only if you have more complex indicators it could become really difficult to solve.

There are other solutions using timer or chartevent, but they have their own drawbacks.

 
Alain Verleyen:

You are right it's confusing.

However there is a simple solution, just refresh you chart (right-click on the chart -> Refresh). This can also be done by code using ChartSetSymbol(0,NULL,0), it will refresh all indicators on all charts using the given symbol. This will work well in most cases, only if you have more complex indicators it could become really difficult to solve.

There are other solutions using timer or chartevent, but they have their own drawbacks.

Just a small (typo) correction : it is ChartSetSymbolPeriod(0,NULL,0) not ChartSetSymbol(0,NULL,0)

PS: when the time frame data is loaded for the first time since the terminal started (the target time frame or the chart time frame), that will not work either

Reason: