Objects display issue

 
Hello there, I'm working on the converting the MT5 version of my EA to MT4 version, and it's not reacting the same on MT4.

Basically it's an EA to do manual backtest on the strategy tester.
As you know the OnChartEvent() function doesn't work on tester, so instead I'm using the OnTick() function to check the state of the objects, buttons to see if they have been clicked and then perform an action.

I use buttons to open and close positions, but also to create HLINEs that I will move on the chart using incremental buttons to set new SL and TP at desired price and then confirm to modify the order.
I use while(true) loop to pause the strategy tester to move my new SL/TP HLINEs, and break; the loop once I validate the new TP and SL to resume the testing.

Here is the MQL4 code:

if(buttonSL.Pressed() || 
   buttonSLup.Pressed() || 
   buttonSLupup.Pressed() || 
   buttonSLdown.Pressed() || 
   buttonSLdowndown.Pressed() ||
   buttonTP.Pressed() || 
   buttonTPup.Pressed() || 
   buttonTPupup.Pressed() || 
   buttonTPdown.Pressed() || 
   buttonTPdowndown.Pressed()) {
            
               // Reset press state
               buttonSL.Pressed(false);
               buttonSLup.Pressed(false);
               buttonSLupup.Pressed(false);
               buttonSLdown.Pressed(false);
               buttonSLdowndown.Pressed(false);
               buttonTP.Pressed(false);
               buttonTPup.Pressed(false);
               buttonTPupup.Pressed(false); 
               buttonTPdown.Pressed(false);
               buttonTPdowndown.Pressed(false);
           
               double tpPrice = OrderTakeProfit();
               double slPrice = OrderStopLoss();
               double currentPrice = OrderType() == OP_BUY ? Bid : Ask;
                       
               // Create TP line
               if (!ObjectCreate(0, "newTPLine", OBJ_HLINE, 0, 0, tpPrice)) {
                   Print("Error creating newTPLine: ", GetLastError());
               }
               ObjectSetInteger(0, "newTPLine", OBJPROP_COLOR, clrGreen);
               ObjectSetInteger(0, "newTPLine", OBJPROP_STYLE, STYLE_SOLID);
               ObjectSetInteger(0, "newTPLine", OBJPROP_WIDTH, 3);
               ObjectSetInteger(0, "newTPLine", OBJPROP_BACK, false);
               
               // Create SL line
               if (!ObjectCreate(0, "newSLLine", OBJ_HLINE, 0, 0, slPrice)) {
                   Print("Error creating newSLLine: ", GetLastError());
               }
               ObjectSetInteger(0, "newSLLine", OBJPROP_COLOR, clrRed);
               ObjectSetInteger(0, "newSLLine", OBJPROP_STYLE, STYLE_SOLID);
               ObjectSetInteger(0, "newSLLine", OBJPROP_WIDTH, 3);
               ObjectSetInteger(0, "newSLLine", OBJPROP_BACK, true);
               
               string tick = (string)CharToString(252);
               // Change CP_SL_Button_ text to "✔"
               buttonSL.Font("Wingdings");
               buttonSL.Text(tick);
   
               // Change CP_TP_Button_ text to "✔"
               buttonTP.Font("Wingdings");
               buttonTP.Text(tick);
               
               ChartRedraw(0);

               while (true) {

                   // Perform new SL/TP HLINEs moving actions here using incremental buttons

                   // Modify position and break; the loop when validating the new SL/TP positions
               }
        }

Here how it looks on MT5 when I click one time on the ++ button to activate the above code:



We can see that:
- The HLINEs have been created correctly
- The ++ button pressed state has been reset to false
- The text of the two buttons on the right changed to validate icon (previously "TP" and "SL")


And here is how it looks on MT4 
when I click one time on the ++ button to activate the above code:



The tester is paused but:
- The two HLINEs are not created, even though they are in the objects list with the good color and good price
- The ++ button remains in pressed state, even though it is supposed to be reset to false right after being pressed
- The TP and SL buttons text was not modified to validate icon, even though it is changed in the object list

It seems that the code is executed but not updated on the chart.

To "trigger" the code to make it work as expected (visible on the chart) I have to click on the chart once or change the scale, and then it looks like on the MT5 version.
I have tried many workarounds to simulate this extra click but nothing worked so far.
It seems that this is related to how MT4 works.

Do you have any idea how I could make it work?

Thank you in advance if you take time to reply.
 

Hi

There are multiple issues with this code but that’s proabably because you showed us only part of the code (not full functionality). So I assume you used here somewhere OrderSelect function to choose the order and get proper prices of SL and TP.

Also, you need to have somewhere break from the while loop, otherwise it will be constantly paused and do nothing.

I have tested your code and it worked, OK the lines were displayed immediately (without any click)- but I think it might be the problem with this while loop here. Try adding some „break” for this loop or something that would slow down this for a while, because now the EA go into this loop and uses all processing power to do nothing (hence the update of the chart is not correct and require some forced action). That’s my assumption here.

Best regards

 
Marzena Maria Szmit #:

Hi

There are multiple issues with this code but that’s proabably because you showed us only part of the code (not full functionality). So I assume you used here somewhere OrderSelect function to choose the order and get proper prices of SL and TP.

Also, you need to have somewhere break from the while loop, otherwise it will be constantly paused and do nothing.

I have tested your code and it worked, OK the lines were displayed immediately (without any click)- but I think it might be the problem with this while loop here. Try adding some „break” for this loop or something that would slow down this for a while, because now the EA go into this loop and uses all processing power to do nothing (hence the update of the chart is not correct and require some forced action). That’s my assumption here.

Best regards

Hello Marzena, thank you for your feedback it's much appreciated.

Yes exactly, I use OrderSelect function to choose the order and it's working properly, but I didn't share this part of the code because I wanted to keep it compact on the forum and focus on the problematic part.

Regarding the content of the while loop, here is what's inside the loop:

while (true) {
                                  
     // Use if statement for each button
     if (POSType == OP_BUY) {
         if (buttonTPupup.Pressed()) {
             TPPRICE += RISK; // TP++ will move the TP 1RR away from entry
             ObjectSetDouble(0, "newTPLine", OBJPROP_PRICE, TPPRICE);
             buttonTPupup.Pressed(false);
             ChartRedraw(0);
             continue;
         } else if (buttonTPup.Pressed()) {
             TPPRICE += 0.25 * RISK; // TP+ will move the TP 0.25RR away from entry
             ObjectSetDouble(0, "newTPLine", OBJPROP_PRICE, TPPRICE);
             buttonTPup.Pressed(false);
             ChartRedraw(0);
             continue;
         } else if (buttonTPdown.Pressed()) {
                
                // Continues like this for all incremental buttons

        }
         
         
     } else if (POSType == OP_SELL) {   
         if (buttonTPupup.Pressed()) {
             TPPRICE -= RISK; // TP++ will move the TP 1RR away from entry
             ObjectSetDouble(0, "newTPLine", OBJPROP_PRICE, TPPRICE);
             buttonTPupup.Pressed(false);
             ChartRedraw(0);
             continue;
         } else if (buttonTPup.Pressed()) {
             TPPRICE -= 0.25 * RISK; // TP+ will move the TP 0.25RR away from entry
             ObjectSetDouble(0, "newTPLine", OBJPROP_PRICE, TPPRICE);
             buttonTPup.Pressed(false);
             ChartRedraw(0);
             continue;
         } else if (buttonTPdown.Pressed()) {

                // Continues like this for all incremental buttons
        }
     }

     // Check if SL or TP Button is clicked to validate new SL and TP position and modify the order
     if (buttonSL.Pressed() || buttonTP.Pressed()) {

        // Code to check if order is BUY or SELL order and make calculations accordingly
        
        // Then OrderModify function here

        // If modification was successful, handle cleanup and UI updates
         if (modificationSuccess) {
             ObjectDelete(0, "newTPLine");
             ObjectDelete(0, "newSLLine");
             buttonSL.Font("Arial");
             buttonTP.Font("Arial");
             buttonSL.Text("SL");
             buttonTP.Text("TP");
             buttonSL.Pressed(false);
             buttonTP.Pressed(false);
             ChartRedraw(0);
             break; // Stop the while loop
         } else if (!modifySL && !modifyTP) {
             // No modification needed as SL and TP are unchanged
             ObjectDelete(0, "newTPLine");
             ObjectDelete(0, "newSLLine");
             buttonSL.Font("Arial");
             buttonTP.Font("Arial");
             buttonSL.Text("SL");
             buttonTP.Text("TP");
             buttonSL.Pressed(false);
             buttonTP.Pressed(false);
             ChartRedraw(0);
             break; // Stop the while loop
         }

     }  // End of while loop


All the functions and mechanisms are working as intented,  but it's just the two HLINEs that are not being display without a click on the chart or on an incremental button.

I tried to use Sleep() within the loop but it didn't work (actually as the Sleep() pauses the while loop for the duration of the Sleep time, the strategy tester resumes for the duration of the Sleep before to pause and resume again, continuously)

I tried to increase the newSL/TP line position by 1 digit on first itteration of the loop, Redraw, and decrease it by 1 digit on the second itteration of the loop to come back to original position and redraw again to see if it would make the lines appear but it didn't work either.

For now the temporary fix that I have implement is putting the while loop in a separate function and use a bool variable to call the while loop function on the next upcoming tick.
Doing so the line are created, and then the while loop starts on the new tick, but it's not ideal because if you run the strategy tester using open price only the next candle can be a big one and trigger the TP or SL before having a chance to modify their positions.

Would you mind sharing the issues you have noticed? I really want to learn and optimize my code.

Thank you again for your feedback!

 
UP!

Does anyone has any idea or had the same issue? I'm still struggling with this issue...
 
Yoloic: I use while(true) loop to pause the strategy tester to move my new SL/TP HLINEs, and break; the loop once I validate the new TP and SL to resume the testing.

You are looping forever, therefor there are no more ticks. Remove the unnecessary loop.

 
The loop is necessary because it's the only way I found to pause the strategy tester (and it works just fine for adjusting new SL/TP positions).
If there is a better solution I'm willing to try but I'm not aware of any. 

My concern is why is the chart not redrawing even though I use ChartRedraw(0), and why does it redraw when clicking on the chart even though there is no more tick and that OnChartEvent() is not supported in strategy tester.
In MQL5/MT5 it's redrawing but in MQL4/MT4 it doesn't behave the same even though the logic is the same.

I use Version 4.0 Build 1420 of MT4.
 
Yoloic #:
The loop is necessary because it's the only way I found to pause the strategy tester (and it works just fine for adjusting new SL/TP positions).
If there is a better solution I'm willing to try but I'm not aware of any. 

My concern is why is the chart not redrawing even though I use ChartRedraw(0), and why does it redraw when clicking on the chart even though there is no more tick and that OnChartEvent() is not supported in strategy tester.
In MQL5/MT5 it's redrawing but in MQL4/MT4 it doesn't behave the same even though the logic is the same.

I use Version 4.0 Build 1420 of MT4.
I think the tester is optimized for testing and only updates chart each tick.  As you have paused it with your loop it will not update the chart