Why do templates not sort objects as they were created?

 

Hello traders,
I wanted to build a simple code that shows my name on a Rectangle Label. So, I wrote it as follows:

//+------------------------------------------------------------------+
//|                                             Object test v1.0.mq5 |
//|                                  Copyright 2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"

string objname_1 = "OBJ_1", objname_2 = "OBJ_2";

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//+------------------------------------------------------------------+
//| Background                                                       |
//+------------------------------------------------------------------+
ObjectCreate(0, objname_1, OBJ_RECTANGLE_LABEL, 0, 0,0,0);

ObjectSetInteger(0, objname_1, OBJPROP_XSIZE, 190);
ObjectSetInteger(0, objname_1, OBJPROP_YSIZE, 70);
ObjectSetInteger(0, objname_1, OBJPROP_XDISTANCE, 10);
ObjectSetInteger(0, objname_1, OBJPROP_YDISTANCE, 60);

//+------------------------------------------------------------------+
//| My Name                                                          |
//+------------------------------------------------------------------+
ObjectCreate(0, objname_2, OBJ_LABEL, 0, 0,0,0);

ObjectSetInteger(0, objname_2, OBJPROP_XDISTANCE, 20);
ObjectSetInteger(0, objname_2, OBJPROP_YDISTANCE, 70);
ObjectSetInteger(0, objname_2, OBJPROP_FONTSIZE, 28);

ObjectSetString(0, objname_2, OBJPROP_TEXT, "Albermawi");

  
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
ObjectDelete(0, objname_1);
ObjectDelete(0, objname_2);
  
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+


After that, I compiled the code as an expert advisor and saved it in a template. Here is the result:

EA Result


The problem is that whenever I apply the template to any chart, my name is gone!

Template Result

While digging into this problem, I found that when I apply the template on a chart, it organizes the objects in a different way than how they were created by the expert advisor.

Comparison


My expert advisor creates the Rectangle Label first, then the Label that carries my name second. But when I call the template, it does the opposite!


So, what did I do wrong here?


How can we organize objects applied by a template in the same way as created by the expert advisor? ... Depending on the ObjectCreate() function

Files:
 
Instruct your EA to delete objects into OnInit before creating them, so they will have your preferred order!
 
Fabio Cavalloni #:
Instruct your EA to delete objects into OnInit before creating them, so they will have your preferred order!
I don't understand what you mean ... Show me the modification that you suggest, please.
 
Muhammad Elbermawi:

Hello traders,
I wanted to build a simple code that shows my name on a Rectangle Label. So, I wrote it as follows:

After that, I compiled the code as an expert advisor and saved it in a template. Here is the result:

The problem is that whenever I apply the template to any chart, my name is gone!

While digging into this problem, I found that when I apply the template on a chart, it organizes the objects in a different way than how they were created by the expert advisor.

My expert advisor creates the Rectangle Label first, then the Label that carries my name second. But when I call the template, it does the opposite!

So, what did I do wrong here?

How can we organize objects applied by a template in the same way as created by the expert advisor? ... Depending on the ObjectCreate() function

What do you want to use to create chart objects? An advisor or a template?

Your template contains both an advisor and one of the chart objects. And the advisor (from the template) creates the same chart object that is contained in the template.

 
Everything is logical. Your template only contains "OBJ_2" and does not contain "OBJ_1" (you can verify this by opening the tpl file with any text editor).
  1. the template creates "OBJ_2";
  2. the advisor creates "OBJ_1";
  3. the advisor's attempt to create "OBJ_2" fails, since "OBJ_2" already exists;

As a result, "OBJ_2" is created earlier than "OBJ_1".

 
Vladislav Boyko #:
Everything is logical. Your template only contains "OBJ_2" and does not contain "OBJ_1" (you can verify this by opening the tpl file with any text editor).
  1. the template creates "OBJ_2";
  2. the advisor creates "OBJ_1";
  3. the advisor's attempt to create "OBJ_2" fails, since "OBJ_2" already exists;

As a result, "OBJ_2" is created earlier than "OBJ_1".

Why does the template store only one object? It should store both when it was created.
 
Muhammad Elbermawi #:
Why does the template store only one object?

I don’t know, it’s your template.😁

In any case, I think you should remove either the chart objects or the EA that creates them from the template. That is, create chart objects either with the EA or with the template, not both.

 
Muhammad Elbermawi #:
Why does the template store only one object? It should store both when it was created.

I can assume that the terminal deliberately does not add OBJ_RECTANGLE_LABEL to the template, since objects of this type cannot be created manually. But this is just my guess, I haven’t checked.

It is best to remove the objects created by the advisor from the template.
 
Vladislav Boyko #:

I can assume that the terminal deliberately does not add OBJ_RECTANGLE_LABEL to the template, since objects of this type cannot be created manually. But this is just my guess, I haven’t checked.

It is best to remove the objects created by the advisor from the template.

This is the point I want to focus on here... I think there is a bug in the way MT5 stores some of the objects created by the ObjectCreate() function in templates... one of them is the "Rectangle Label".

To prove my point:

  • I will add the same objects to a new chart, but I will do it manually this time.
  • I will save it as a new template. I will call it “Manual Name.tpl”
  • Now I will load the template on a new chart.
  • And everything works fine this time.

Manual Results 1


Guess what, the template can now create the Rectangle Label on the new chart because it is already stored inside it ... Plus, it does it correctly in the same order as I created it.

Here is the code of the new template ... as you can see, it saved the Rectangle Label object that I created manually.

<chart>
id=133969451336792660
symbol=CADJPY.m
description=Canadian Dollar vs Japanese Yen
period_type=1
period_size=1
digits=3
tick_size=0.000000
position_time=1752555600
scale_fix=0
scale_fixed_min=107.220000
scale_fixed_max=108.770000
scale_fix11=0
scale_bar=0
scale_bar_val=1.000000
scale=8
mode=1
fore=0
grid=0
volume=0
scroll=1
shift=1
shift_size=29.559748
fixed_pos=0.000000
ticker=1
ohlc=0
one_click=0
one_click_btn=1
bidline=1
askline=0
lastline=0
days=0
descriptions=0
tradelines=1
tradehistory=1
window_left=130
window_top=130
window_right=957
window_bottom=559
window_type=1
floating=0
floating_left=0
floating_top=0
floating_right=0
floating_bottom=0
floating_type=1
floating_toolbar=1
floating_tbstate=
background_color=0
foreground_color=16777215
barup_color=65535
bardown_color=65535
bullcandle_color=0
bearcandle_color=16777215
chartline_color=65535
volumes_color=3329330
grid_color=10061943
bidline_color=10061943
askline_color=255
lastline_color=49152
stops_color=255
windows_total=1

<window>
height=0.261135
objects=2

<indicator>
name=Main
path=
apply=1
show_data=1
scale_inherit=0
scale_line=0
scale_line_percent=50
scale_line_value=0.000000
scale_fix_min=0
scale_fix_min_val=0.000000
scale_fix_max=0
scale_fix_max_val=0.000000
expertmode=0
fixed_height=-1
</indicator>
<object>
type=110
name=H1 Rectangle Label 59700
color=0
pos_x=10
pos_y=60
size_x=190
size_y=70
bgcolor=15790320
refpoint=0
border_type=0
</object>

<object>
type=102
name=H1 Label 48018
descr=Albermawi
style=1
angle=0
pos_x=20
pos_y=70
fontsz=28
fontnm=Arial
anchorpos=0
refpoint=0
</object>

</window>
</chart>


Depending on this example and the one I show in post #1, I think that objects like “Rectangle Label” can be stored in templates if they are created manually, but they cannot be stored in templates if they are created automatically using the ObjectCreate() function. Which opens the door to an important question ... Why do templates not work with the Object Create() function?

Files:
 
Muhammad Elbermawi #:
I think that objects like “Rectangle Label” can be stored in templates if they are created manually

So I was wrong. I wrote that it was just my guess, made off the cuff.

Muhammad Elbermawi #:
Why do templates not work with the Object Create() function?

ObjectCreate() cannot create an object that already exists. The object already exists because it was created by the template before your code ran.

Muhammad Elbermawi #:
but they cannot be stored in templates if they are created automatically using the ObjectCreate() function

This is a dubious statement, I don't have time to try to reproduce it. Even if it is true, it doesn't matter, because the template should not contain objects created by MQL programs, otherwise it is fraught with situations described in your first post.

[edit]

I think if you remove "OBJ_2" from the template (which is attached to your first post) it should solve the problem you described.

 
Muhammad Elbermawi:

I wanted to build a simple code that shows my name on a Rectangle Label. So, I wrote it as follows:

After that, I compiled the code as an expert advisor and saved it in a template. Here is the result:

The problem is that whenever I apply the template to any chart, my name is gone!

While digging into this problem, I found that when I apply the template on a chart, it organizes the objects in a different way than how they were created by the expert advisor.

My expert advisor creates the Rectangle Label first, then the Label that carries my name second. But when I call the template, it does the opposite!

So, what did I do wrong here?

How can we organize objects applied by a template in the same way as created by the expert advisor? ... Depending on the ObjectCreate() function

Most likely the effect you're observing is due to the fact that MT5 is highly asynchronous thing AND your initial template contains EA itself along with the objects it manages. Your second "manual" template does not contain EA, hence it does not interfere with object creation/deletion.

When you apply a template with EA on a chart with another EA, happens many processes:

  • the old EA executes OnDeinit handler (it can "ask" to delete some objects),
  • the new EA executes OnInit handler (it can "ask" to create some objects),
  • anywhere inbetween the terminal itself deletes old objects
  • and creates new objects (if exist in the template).

The exact sequence is not guaranteed, because every point is executed in a separate thread, and all actions with the objects are queued and applied in postponed manner! As a result, the request to delete objects (or a specific object) from old EA can be processed after the request to create object with the same name from new EA, and since you use the same name for objects in both instances of EA, they can interfere. You observe this as changing of the order of the objects.

More details on this you can find in the codebase. The only difference is that the lib considers initially a situation of changing symbol and/or timeframe of a chart, but applying a template invokes similar processes, and even more.

If you want to solve the problem programmatically in your EA, you can create objects with a unique suffix (random or ms timestamp chosen in OnInit) and delete them in OnDeinit only by complete names including the required suffix. I suppose, if you do so and save a template with both objects and EA, then after template re-application you'll find number of objects is even increased by 2, every time ;-). So, indeed, it's a bad idea to store EA and its objects in the same template - you need to decide how to devide responsibility between EA and template.

Init_Sync
Init_Sync
  • 2017.05.29
  • www.mql5.com
The library makes indicators' Init/Deinit synchronized