ObjectCreate in Strategy Tester not working when a separate indicator subwindow is targeted.

 

Hi guys,


Is it possible to create objects (e.g.: OBJ_TREND) in the strategy tester in a separate indicator subwindow?

  1. I loaded an indicator from my EA using iCustom,
  2. I added it to the chart using ChartIndicatorAdd (separate subwindow),
  3. I started to draw trend lines into this new indicator subwindow in the OnTick function, when new data is available.

When running normally, everything just works.

However, when running the EA via the strategy tester (visual mode), these drawings are not shown.

Interestingly, when I change the ObjectCreate subwindow parameter from 1 to 0 (main window), it works.


Am I missing something, or is it correct, that in the tester you can only draw on the main chart, but not onto separate indicator windows?


Thanks in advance,

Benjamin


 

Preparation is done in OnInit.

The indicator itself must be searched for in OnTick (). You can walk through the breakpoints in code and explore for yourself.

//+------------------------------------------------------------------+
//|                             Draw in the iCustom iMACD window.mq5 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//--- input parameters
input group             "MACD"
input int                  Inp_MACD_fast_ema_period= 12;          // MACD: period for Fast average calculation
input int                  Inp_MACD_slow_ema_period= 26;          // MACD: period for Slow average calculation
input int                  Inp_MACD_signal_period  = 9;           // MACD: period for their difference averaging
input ENUM_APPLIED_PRICE   Inp_MACD_applied_price  = PRICE_CLOSE; // MACD: type of price
//---
int   handle_iMACD;                          // variable for storing the handle of the iMACD indicator
int   indicator_sub_window=-1;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create handle of the indicator iMACD
   handle_iMACD=iCustom(Symbol(),Period(),"Examples\\MACD",Inp_MACD_fast_ema_period,Inp_MACD_slow_ema_period,
                        Inp_MACD_signal_period,Inp_MACD_applied_price);
//--- if the handle is not created
   if(handle_iMACD==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iMACD indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_FAILED);
     }
//---
   int windows_total=(int)ChartGetInteger(ChartID(),CHART_WINDOWS_TOTAL,0);
   ResetLastError();
   if(!ChartIndicatorAdd(ChartID(),windows_total,handle_iMACD))
      Print("ERROR: ChartIndicatorAdd error ",GetLastError());
   windows_total=(int)ChartGetInteger(ChartID(),CHART_WINDOWS_TOTAL,0);
   for(int i=windows_total-1; i>=0; i--)
     {
      int indicators_total=ChartIndicatorsTotal(0,i);
      for(int j=indicators_total-1; j>=0; j--)
        {
         string indicator_name=ChartIndicatorName(0,i,j);
         Print("  Subwindow ",i,", Indicator ",indicator_name);
        }
     }
//---
   int windows_macd=ChartWindowFind(ChartID(),"MACD("+
                                    IntegerToString(Inp_MACD_fast_ema_period)+","+
                                    IntegerToString(Inp_MACD_slow_ema_period)+","+
                                    IntegerToString(Inp_MACD_signal_period)+")");
//--- create a vertical line
   if(!ObjectCreate(ChartID(),"HLine",OBJ_HLINE,windows_total,0,0.0))
     {
      Print(__FUNCTION__,
            ": failed to create a vertical line! Error code = ",GetLastError());
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   if(handle_iMACD!=INVALID_HANDLE)
      IndicatorRelease(handle_iMACD);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   int windows_macd=ChartWindowFind(ChartID(),"MACD("+
                                    IntegerToString(Inp_MACD_fast_ema_period)+","+
                                    IntegerToString(Inp_MACD_slow_ema_period)+","+
                                    IntegerToString(Inp_MACD_signal_period)+")");
   if(ObjectFind(ChartID(),"HLine")<0)
      //--- create a vertical line
      if(!ObjectCreate(ChartID(),"HLine",OBJ_HLINE,windows_macd,0,0.0))
        {
         Print(__FUNCTION__,
               ": failed to create a vertical line! Error code = ",GetLastError());
        }
   int d=0;
  }
//+------------------------------------------------------------------+
 
Vladimir Karputov:

Preparation is done in OnInit.

The indicator itself must be searched for in OnTick (). You can walk through the breakpoints in code and explore for yourself.

Thank you so much! I'll investigate the code.