Creating objects on multiple charts simultaneously in a backtest

 

hi, i was wondering whether it is possible to create objects on multiple charts simultaneously in a backtest. The following code is obviously basic, I've made it simplier so i wouldn/t exceed character usage but its supposed to be able to identify types of candles and does so perfectly. However, despite only two symbols within the 'symbol_loop', the objects created will only create for just one symbol and timeframe, despite using two symbols and two timeframes. I've attached screenshots, the visualize backtest of EURUSD 1h works perfectly but the other charts look like the second screenshot of EURUSD 15m. I've tested the code, this has nothing to do with recognizing the candlesticks on different timeframes, simply an inability to create those objects for different charts. Can i fix this so that all symbols and timeframes considered will create objects for the chart as the EURUSD 1H example I've shown? And if so, how can that be achieved? I've also attached the settings I've used. Thanks for the help in advance!


string symbol_loop[] = {"EURUSD", "GBPCAD"};
ENUM_TIMEFRAMES timeframe_loop[] = {PERIOD_M15, PERIOD_H1};

int maHandle[];

datetime old_time;

int OnInit()
  {
   ArrayResize(maHandle, ArraySize(symbol_loop));

   for(int i = 0; i < ArraySize(symbol_loop); i++)
     {
      maHandle[i] = iMA(symbol_loop[i], PERIOD_H1, 14, 0, MODE_SMA, PRICE_CLOSE);
     }

   return(INIT_SUCCEEDED);
  }

void OnTick()
{  
   datetime GMT = iTime(_Symbol, PERIOD_H1, 1);
   if(GMT > old_time)
   {
      old_time = GMT;

      for(int i = 0; i < ArraySize(symbol_loop); i++)
      {
         string symbol = symbol_loop[i];

         for(int j = 0; j < ArraySize(timeframe_loop); j++)
         {
            ENUM_TIMEFRAMES timeframe = timeframe_loop[j];
         
            double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE);
            double contractSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_CONTRACT_SIZE);
            double point = tickValue / contractSize;
            double PipValue = point * 10;               
          
              
            double Open = open(symbol, timeframe, 1);
            double Close = close(symbol, timeframe, 1);
            double Low = low(symbol, timeframe, 1);
            double High = high(symbol, timeframe, 1);
  
      
            //Current
            double Open0 = open(symbol, timeframe, 0);       
  
            double ma[];
            ArraySetAsSeries(ma, true);
            CopyBuffer(maHandle[i], 0, 0, 1, ma);
            double MA_Value = ma[0];

            bool BuyingHammerConfirmed     = BuyingHammerSignal(Low, old_time, High, symbol);
    

      }  
      }
   }
}

double open(string symbol, ENUM_TIMEFRAMES timeframe, int shift)
  {
   return iOpen(symbol, timeframe, shift);
  }

double close(string symbol, ENUM_TIMEFRAMES timeframe, int shift)
  {
   return iClose(symbol, timeframe, shift);
  }

double high(string symbol, ENUM_TIMEFRAMES timeframe, int shift)
  {
   return iHigh(symbol, timeframe, shift);
  }

double low(string symbol, ENUM_TIMEFRAMES timeframe, int shift)
  {
   return iLow(symbol, timeframe, shift);
  }


bool BuyingHammerSignal(double pLow, datetime ptime, double pHigh, string psymbol)
  {
   
   if(pHigh > pLow){
   
      createObject(ptime, pLow, 233, 1, clrAntiqueWhite, " H 1H", psymbol);
   }

   return false;
  }


void createObject(datetime time, double price, int arrowcode, int direction, color clr, string txt, string psymbol)
  {
   string objName = "";
   StringConcatenate(objName, "Signal@", " ", psymbol, " ", time, " at ", DoubleToString(price, _Digits), " (", arrowcode, ")");

   if(ObjectCreate(0, objName, OBJ_ARROW, 0, time, price))
     {
      ObjectSetInteger(0, objName, OBJPROP_ARROWCODE, arrowcode);
      ObjectSetInteger(0, objName, OBJPROP_COLOR, clr);
      ObjectSetString(0, objName, OBJPROP_SYMBOL, psymbol);
      if(direction > 0)
         ObjectSetInteger(0, objName, OBJPROP_ANCHOR, ANCHOR_TOP);
      if(direction < 0)
         ObjectSetInteger(0, objName, OBJPROP_ANCHOR, ANCHOR_BOTTOM);
     }

   string objectNameDesc = objName + txt;
   if(ObjectCreate(0, objectNameDesc, OBJ_TEXT, 0, time, price))
     {
      ObjectSetString(0, objectNameDesc, OBJPROP_TEXT, " " + txt);
      ObjectSetInteger(0, objectNameDesc, OBJPROP_COLOR, clr);
      if(direction > 0)
         ObjectSetInteger(0, objectNameDesc, OBJPROP_ANCHOR, ANCHOR_TOP);
      if(direction < 0)
         ObjectSetInteger(0, objectNameDesc, OBJPROP_ANCHOR, ANCHOR_BOTTOM);
     }
  }




Files:
 

Graphical Objects are not created on "symbols". They are created on "charts", irrespective of what symbol they may be displaying.

The object property "OBJPROP_SYMBOL" is not for that purpose, and its for the "OBJ_CHART" graphical object.

All your object creations are on the chart id 0, which is simply the current chart.

If you want to create the graphical objects in other charts, you need to identify the chart id of those charts and use that chart id when creating the objects.

 

You have asked this question before ... Creating objects on multiple charts

And you were given an answer ... https://www.mql5.com/en/forum/455871#comment_50234941

Why are you not applying it?

Creating objects on multiple charts
Creating objects on multiple charts
  • 2023.10.17
  • www.mql5.com
Hi Everyone, not entirely how this works since this is my first post:) Everything in this EA works fine, i tested it all multiple times...