MT5 Multitimeframe Backtest and Indicator draw trendline

 

I have create a very simple EA which calls 4 times the same indicator from different timeframes.

//+------------------------------------------------------------------+
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"


//---
int MA_handle;
int MA_handle2;
int MA_handle3;
int MA_handle4;
int MA_handle5;


//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
  
  MA_handle=iCustom(NULL,PERIOD_H1,"Custom5");
  MA_handle2=iCustom(NULL,PERIOD_H4,"Custom5");
  MA_handle3=iCustom(NULL,PERIOD_D1,"Custom5");
  MA_handle4=iCustom(NULL,PERIOD_W1,"Custom5");
 
   return(0);
  }



//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- release our indicator handles
   IndicatorRelease(MA_handle);
   IndicatorRelease(MA_handle2);
   IndicatorRelease(MA_handle3);
   IndicatorRelease(MA_handle4);
   IndicatorRelease(MA_handle5);
  }



//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
return;
 }
//+---------------------------------------------------------------------------------------------------------+
//|                                                                                                         |
//+---------------------------------------------------------------------------------------------------------+


That way i can watch all 4 timeframes how they develop with the indicators on the chart.


But now i have find a problem, i have create a simple indicator which just draw a trendline from last high to current high. The problem is when i call this indicator with my EA on the backtester visual mode, it draw all 4 trendlines into the same chart, but i want him to draw every trendline in the own chart, so for example the H4 timeframe is running in the visual mode backtester then he should draw the trendline also in this H4 chart.

Does the MT5 backtester dont allow to draw objects on other timeframe charts or must i just change my indicator code?

Here is the code from my indicator "Custom5":

//+------------------------------------------------------------------+
//|                                                      Custom5.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


//--- input parameters of the script

input color           InpColor=clrWhite;     // Line color
input ENUM_LINE_STYLE InpStyle=STYLE_SOLID; // Line style
input int             InpWidth=2;          // Line width
input bool            InpBack=false;       // Background line
input bool            InpSelection=true;   // Highlight to move
input bool            InpRayLeft=false;    // Line's continuation to the left
input bool            InpRayRight=true;   // Line's continuation to the right
input bool            InpHidden=true;      // Hidden in the object list
input long            InpZOrder=0;         // Priority for mouse click
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   
//---
   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[])
  {
//---

   ArraySetAsSeries(time,true);
   ArraySetAsSeries(open,true);
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   ArraySetAsSeries(close,true);


   string InpName="Trend"+DoubleToString(_Period,0);     // Line name
   
   TrendDelete(ChartID(),InpName);
   TrendCreate(ChartID(),InpName,0,time[5],high[5],time[0],high[0],InpColor,InpStyle,
   InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder);

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



//+------------------------------------------------------------------+
//| Create a trend line by the given coordinates                     |
//+------------------------------------------------------------------+
bool TrendCreate(const long            chart_ID=0,        // chart's ID
                 const string          name="TrendLine",  // line name
                 const int             sub_window=0,      // subwindow index
                 datetime              time1=0,           // first point time
                 double                price1=0,          // first point price
                 datetime              time2=0,           // second point time
                 double                price2=0,          // second point price
                 const color           clr=clrRed,        // line color
                 const ENUM_LINE_STYLE style=STYLE_SOLID, // line style
                 const int             width=1,           // line width
                 const bool            back=false,        // in the background
                 const bool            selection=true,    // highlight to move
                 const bool            ray_left=false,    // line's continuation to the left
                 const bool            ray_right=false,   // line's continuation to the right
                 const bool            hidden=true,       // hidden in the object list
                 const long            z_order=0)         // priority for mouse click
  {
//--- set anchor points' coordinates if they are not set
   ChangeTrendEmptyPoints(time1,price1,time2,price2);
//--- reset the error value
   ResetLastError();
//--- create a trend line by the given coordinates
   if(!ObjectCreate(chart_ID,name,OBJ_TREND,sub_window,time1,price1,time2,price2))
     {
      Print(__FUNCTION__,
            ": failed to create a trend line! Error code = ",GetLastError());
      return(false);
     }
//--- set line color
   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- set line display style
   ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- set line width
   ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- display in the foreground (false) or background (true)
   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of moving the line by mouse
//--- when creating a graphical object using ObjectCreate function, the object cannot be
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- enable (true) or disable (false) the mode of continuation of the line's display to the left
   ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- enable (true) or disable (false) the mode of continuation of the line's display to the right
   ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- hide (true) or display (false) graphical object name in the object list
   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
//| Move trend line anchor point                                     |
//+------------------------------------------------------------------+
bool TrendPointChange(const long   chart_ID=0,       // chart's ID
                      const string name="TrendLine", // line name
                      const int    point_index=0,    // anchor point index
                      datetime     time=0,           // anchor point time coordinate
                      double       price=0)          // anchor point price coordinate
  {
//--- if point position is not set, move it to the current bar having Bid price
   if(!time)
      time=TimeCurrent();
   if(!price)
      price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
   ResetLastError();
//--- move trend line's anchor point
   if(!ObjectMove(chart_ID,name,point_index,time,price))
     {
      Print(__FUNCTION__,
            ": failed to move the anchor point! Error code = ",GetLastError());
      return(false);
     }
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
//| The function deletes the trend line from the chart.              |
//+------------------------------------------------------------------+
bool TrendDelete(const long   chart_ID=0,       // chart's ID
                 const string name="TrendLine") // line name
  {
//--- reset the error value
   ResetLastError();
//--- delete a trend line
   if(!ObjectDelete(chart_ID,name))
     {
      Print(__FUNCTION__,
            ": failed to delete a trend line! Error code = ",GetLastError());
      return(false);
     }
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
//| Check the values of trend line's anchor points and set default   |
//| values for empty ones                                            |
//+------------------------------------------------------------------+
void ChangeTrendEmptyPoints(datetime &time1,double &price1,
                            datetime &time2,double &price2)
  {
//--- if the first point's time is not set, it will be on the current bar
   if(!time1)
      time1=TimeCurrent();
//--- if the first point's price is not set, it will have Bid value
   if(!price1)
      price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- if the second point's time is not set, it is located 9 bars left from the second one
   if(!time2)
     {
      //--- array for receiving the open time of the last 10 bars
      datetime temp[10];
      CopyTime(Symbol(),Period(),time1,10,temp);
      //--- set the second point 9 bars left from the first one
      time2=temp[0];
     }
//--- if the second point's price is not set, it is equal to the first point's one
   if(!price2)
      price2=price1;
  }
 
can the mt5 not draw trendline objects on other charts in multitimeframe backtest, maybe somebody can just answer this small question?
 

You could use a switch.

switch(Period())
{
 case PERIOD_H1:
  {
   // draw H1 trend
  }
 break;

 case PERIOD_H4:
  {
   // draw H4 trend
  }
 break;
}

If you want to draw on other charts you have to use the:

ChartID();
 
Marco vd Heijden:

You could use a switch.

If you want to draw on other charts you have to use the:


Thank you for your help, i did not get a notification so i did not know somebody have write me in the forum.

I have create a simple MT5 EA which use ChartID() to draw trendline objects, normaly he should draw on the H1 and D1 chart a trendline, but i see that he again draw both trendlines in the same H1 chart.

Can you please copy and paste my example EA and tell me what i have code wrong?


//+------------------------------------------------------------------+
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"


//---

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   return(0);
  }



//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- release our indicator handles
  }



//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  color           InpColor=clrWhite;     // Line color
  ENUM_LINE_STYLE InpStyle=STYLE_SOLID; // Line style
  int             InpWidth=2;          // Line width
  bool            InpBack=false;       // Background line
  bool            InpSelection=true;   // Highlight to move
  bool            InpRayLeft=false;    // Line's continuation to the left
  bool            InpRayRight=true;   // Line's continuation to the right
  bool            InpHidden=true;      // Hidden in the object list
  long            InpZOrder=0;         // Priority for mouse click

 
  datetime Time[];  
  datetime Time2[];
  ArraySetAsSeries(Time,true);
  ArraySetAsSeries(Time2,true);
  CopyTime(_Symbol,PERIOD_H1,0,10,Time);
  CopyTime(_Symbol,PERIOD_D1,0,10,Time2);
  
  
  double High[];  
  double High2[];
  ArraySetAsSeries(High,true);
  ArraySetAsSeries(High2,true);
  CopyHigh(_Symbol,PERIOD_H1,0,10,High);
  CopyHigh(_Symbol,PERIOD_D1,0,10,High2);
  
  double Low[];  
  double Low2[];
  ArraySetAsSeries(Low,true);
  ArraySetAsSeries(Low2,true);
  CopyLow(_Symbol,PERIOD_H1,0,10,Low);
  CopyLow(_Symbol,PERIOD_D1,0,10,Low2);
  
  double Close[];  
  double Close2[];
  ArraySetAsSeries(Close,true);
  ArraySetAsSeries(Close2,true);
  CopyClose(_Symbol,PERIOD_H1,0,10,Close);
  CopyClose(_Symbol,PERIOD_D1,0,10,Close2);

  
   string InpName="Trend"+DoubleToString(_Period,0);     // Line name
   
   TrendDelete(ChartID(),InpName);
   TrendCreate(ChartID(),InpName,0,Time[5],High[5],Time[0],High[0],InpColor,InpStyle,
   InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder);

   string InpName2="line";
   TrendDelete(ChartID(),InpName2);
   TrendCreate(ChartID(),InpName2,0,Time2[5],High2[5],Time2[0],High2[0],InpColor,InpStyle,
   InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder);

return;
 }
//+---------------------------------------------------------------------------------------------------------+
//|                                                                                                         |
//+---------------------------------------------------------------------------------------------------------+





//+------------------------------------------------------------------+
//| Create a trend line by the given coordinates                     |
//+------------------------------------------------------------------+
bool TrendCreate(const long            chart_ID=0,        // chart's ID
                 const string          name="TrendLine",  // line name
                 const int             sub_window=0,      // subwindow index
                 datetime              time1=0,           // first point time
                 double                price1=0,          // first point price
                 datetime              time2=0,           // second point time
                 double                price2=0,          // second point price
                 const color           clr=clrRed,        // line color
                 const ENUM_LINE_STYLE style=STYLE_SOLID, // line style
                 const int             width=1,           // line width
                 const bool            back=false,        // in the background
                 const bool            selection=true,    // highlight to move
                 const bool            ray_left=false,    // line's continuation to the left
                 const bool            ray_right=false,   // line's continuation to the right
                 const bool            hidden=true,       // hidden in the object list
                 const long            z_order=0)         // priority for mouse click
  {
//--- set anchor points' coordinates if they are not set
   ChangeTrendEmptyPoints(time1,price1,time2,price2);
//--- reset the error value
   ResetLastError();
//--- create a trend line by the given coordinates
   if(!ObjectCreate(chart_ID,name,OBJ_TREND,sub_window,time1,price1,time2,price2))
     {
      Print(__FUNCTION__,
            ": failed to create a trend line! Error code = ",GetLastError());
      return(false);
     }
//--- set line color
   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- set line display style
   ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- set line width
   ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- display in the foreground (false) or background (true)
   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of moving the line by mouse
//--- when creating a graphical object using ObjectCreate function, the object cannot be
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- enable (true) or disable (false) the mode of continuation of the line's display to the left
   ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- enable (true) or disable (false) the mode of continuation of the line's display to the right
   ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- hide (true) or display (false) graphical object name in the object list
   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
//| Move trend line anchor point                                     |
//+------------------------------------------------------------------+
bool TrendPointChange(const long   chart_ID=0,       // chart's ID
                      const string name="TrendLine", // line name
                      const int    point_index=0,    // anchor point index
                      datetime     time=0,           // anchor point time coordinate
                      double       price=0)          // anchor point price coordinate
  {
//--- if point position is not set, move it to the current bar having Bid price
   if(!time)
      time=TimeCurrent();
   if(!price)
      price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
   ResetLastError();
//--- move trend line's anchor point
   if(!ObjectMove(chart_ID,name,point_index,time,price))
     {
      Print(__FUNCTION__,
            ": failed to move the anchor point! Error code = ",GetLastError());
      return(false);
     }
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
//| The function deletes the trend line from the chart.              |
//+------------------------------------------------------------------+
bool TrendDelete(const long   chart_ID=0,       // chart's ID
                 const string name="TrendLine") // line name
  {
//--- reset the error value
   ResetLastError();
//--- delete a trend line
   if(!ObjectDelete(chart_ID,name))
     {
      Print(__FUNCTION__,
            ": failed to delete a trend line! Error code = ",GetLastError());
      return(false);
     }
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
//| Check the values of trend line's anchor points and set default   |
//| values for empty ones                                            |
//+------------------------------------------------------------------+
void ChangeTrendEmptyPoints(datetime &time1,double &price1,
                            datetime &time2,double &price2)
  {
//--- if the first point's time is not set, it will be on the current bar
   if(!time1)
      time1=TimeCurrent();
//--- if the first point's price is not set, it will have Bid value
   if(!price1)
      price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- if the second point's time is not set, it is located 9 bars left from the second one
   if(!time2)
     {
      //--- array for receiving the open time of the last 10 bars
      datetime temp[10];
      CopyTime(Symbol(),Period(),time1,10,temp);
      //--- set the second point 9 bars left from the first one
      time2=temp[0];
     }
//--- if the second point's price is not set, it is equal to the first point's one
   if(!price2)
      price2=price1;
  }
 
MQLUsername:


Thank you for your help, i did not get a notification so i did not know somebody have write me in the forum.

I have create a simple MT5 EA which use ChartID() to draw trendline objects, normaly he should draw on the H1 and D1 chart a trendline, but i see that he again draw both trendlines in the same H1 chart.

Can you please copy and paste my example EA and tell me what i have code wrong?


It's not possible currently to draw on other charts within the Strategy Tester.
 
ok thanks for the info
 
I think you must change code to draw trendline as buffer of indicator.
 
Trinh Dat:
I think you must change code to draw trendline as buffer of indicator.

that could be possible because i did also see that indicators like moving average or rsi are display in the strategy tester charts from other timeframes. but it can be little bit to difficult to code that. easyer could be to code a period converter for MT4 which update offline charts during backtest, i did see some youtube videos where people show how it works. then you can put your template with all indicators which you want on the offline charts.

Reason: