Problem with ObjectsDeleteAll... because function uses a synchronous call? ...what to do?

 

Hi everyone, I don't think this has been asked yet...

In the documentation on ObjectsDeleteAll(), you can read:

ObjectsDeleteAll

"Note:

The function uses a synchronous call, which means that the function waits for the execution of all commands that have been enqueued for this chart prior to its call, that is why this function can be time consuming. This feature should be taken into account when working with a large number of objects on a chart."

I think this is the reason I'm having issues with my code and I can't find the solution. I created a replica of the issue with the code below. This represents the way I am trying to make my code work at this time. As you can see if you compile this code, I use the EA's settings to turn labels ON/OFF and then the code uses a for loop to draw the active labels one below the other starting from the top of the page. But this doesn't work because the function to delete all labels doesn't get called immediately. Instead, it gets called after the rest of the OnInit function has been processed, which leaves me with no labels. My only workaround so far is to open the EA's settings without changing anything and then clicking OK, then the labels will appear (you need to do that to see the labels the first time you load the below code on a chart). I am trying to avoid having to that as it becomes really tedious and confusing in the context of how I use the EA. I know I can have the labels drawn with the OnTick function but I also want to be able to use this during the weekend. So I'm open to suggestions... thanks in advance!

By the way this will also happen every time you change the settings. For some reason, anytime you change the settings, the code won't work properly until you re-open the settings a click OK again. I wish I knew why this happened but I have no clue.

PS: I'm not sure exactly why this happens, I made an assumption about the ObjectsDeleteAll command being called after the other commands are processed but I haven't been able to confirm this yet.

input bool Draw_label_1 = true;
input bool Draw_label_2 = true;

long chart = (long)_Symbol;
int label_y_spacing = 50;
string labels[];

void OnInit() {
	
	int labels_count = 0;
	
	if (Draw_label_1) {
		labels_count++;
		ArrayResize(labels,labels_count);
		labels[labels_count - 1] = "Label 1";
	}
	if (Draw_label_2) {
		labels_count++;
		ArrayResize(labels,labels_count);
		labels[labels_count - 1] = "Label 2";
	}
	
	ObjectsDeleteAll(chart,0,OBJ_LABEL);
	
	for (int i = 0; i < labels_count; i++ ) {
	
		ObjectCreate(chart,labels[i],OBJ_LABEL,0,0,0);
   		ObjectSetInteger(chart,labels[i],OBJPROP_FONTSIZE,50);
   		ObjectSetString(chart,labels[i],OBJPROP_TEXT,labels[i]);
   		ObjectSetInteger(chart,labels[i],OBJPROP_YDISTANCE,i * label_y_spacing);   	
	
	}	

} 

edit: I tried another solution which was to individually delete only the inactive labels when OnInit was called after a settings change, but it still doesn't work. So this problem is making my head spin; I can't understand what is causing the issue. I first thought the command to delete labels was being processed after the command to create them which resulted in no labels showing. But with the new tests I'm doing, it seems more complicated than that for a reason I can't understand.


Documentation on MQL5: Integration / MetaTrader for Python / order_calc_margin
Documentation on MQL5: Integration / MetaTrader for Python / order_calc_margin
  • www.mql5.com
order_calc_margin - MetaTrader for Python - Integration - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 

ChartRedraw(); ?

void OnInit() {
        
        int labels_count = 0;
        
        if (Draw_label_1) {
                labels_count++;
                ArrayResize(labels,labels_count);
                labels[labels_count - 1] = "Label 1";
        }
        if (Draw_label_2) {
                labels_count++;
                ArrayResize(labels,labels_count);
                labels[labels_count - 1] = "Label 2";
        }
        
        ObjectsDeleteAll(chart,0,OBJ_LABEL);
        
        for (int i = 0; i < labels_count; i++ ) {
        
           ObjectCreate(chart,labels[i],OBJ_LABEL,0,0,0);
        ObjectSetInteger(chart,labels[i],OBJPROP_FONTSIZE,50);
        ObjectSetString(chart,labels[i],OBJPROP_TEXT,labels[i]);
        ObjectSetInteger(chart,labels[i],OBJPROP_YDISTANCE,i * label_y_spacing);        
        
        }       
   ChartRedraw(); // ??
} 
 
Amir Yacoby #:

ChartRedraw(); ?

lol, that was so simple I feel stupid. Thanks a lot my friend!

I was about to edit my post before I saw your reply because I realized that ObjectCreate was also a "synchronous" call... meaning my code didn't work well even if I removed the command to delete objects. I had never used ChartRedraw before so it never came to mind.

Thanks again! That solves everything...