Sleep() within a while() Loop

 

Why is the sleep function not working properly within a while loop?

bool loaded = false;

while (!loaded)
   {
      if (CopyTime(BCIndex, PERIOD_CURRENT, time[start_pos - 1], time[rates_total - 1], BCtime) != -1 && CopyTime(PCIndex, PERIOD_CURRENT, time[start_pos - 1], time[rates_total - 1], PCtime) != -1) break;
      else
      {
         Print("CopyTime failed!");
         Sleep(1500);
      }
   }

it seems the sleep function has no effect. the log shows following (i've cut the log, it's repeating almost 50 times per 1ms):

2023.10.13 20:21:01.414 Index STCatcher (EURUSD,M30)    CopyTime failed!
2023.10.13 20:21:01.415 Index STCatcher (EURUSD,M30)    CopyTime failed!
2023.10.13 20:21:01.416 Index STCatcher (EURUSD,M30)    CopyTime failed!
2023.10.13 20:21:01.417 Index STCatcher (EURUSD,M30)    CopyTime failed!
2023.10.13 20:21:01.418 Index STCatcher (EURUSD,M30)    CopyTime failed!
2023.10.13 20:21:01.419 Index STCatcher (EURUSD,M30)    CopyTime failed!
Documentation on MQL5: Common Functions / Sleep
Documentation on MQL5: Common Functions / Sleep
  • www.mql5.com
Sleep - Common Functions - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 

If this is for an Indicator, then please note that the Sleep function is not supported in Indicators.

  • The Sleep() function can't be called for custom indicators, because indicators are executed in the interface thread and must not slow down it. The function has the built-in check of EA halt flag every 0.1 seconds.
Documentation on MQL5: Common Functions / Sleep
Documentation on MQL5: Common Functions / Sleep
  • www.mql5.com
Sleep - Common Functions - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Fernando Carreiro #: If this perhaps in an Indicator? If so, then please note that the Sleep function is not supported in Indicators.
  • The Sleep() function can't be called for custom indicators, because indicators are executed in the interface thread and must not slow down it. The function has the built-in check of EA halt flag every 0.1 seconds.

yes, I didn't notice this, sorry.

is there another way to repeat it after a certain time if failed? if I put a simple "return", and the market is closed, it will not repeat until market is open again. and the further calculations depend on a success of this function.

 
Anas Morad:

Why is the sleep function not working properly within a while loop?

it seems the sleep function has no effect. the log shows following (i've cut the log, it's repeating almost 50 times per 1ms):

To me it seems the context in which you need that is somewhat out of scope.

Maybe you could share the code so that it is possible to see what you are actually trying to achieve.
 

you will need to create a function to force a delay within an indicator.... this is mine

void Wait(int Seconds) 
{

datetime StartTime= Seconds + TimeTradeServer();
   while (TimeTradeServer()<StartTime)
   {
  //do nothing in betweem
   }
}
 
Anas Morad #:

yes, I didn't notice this, sorry.

is there another way to repeat it after a certain time if failed? if I put a simple "return", and the market is closed, it will not repeat until market is open again. and the further calculations depend on a success of this function.

compare time, something like this, just wrote the code for idea, not tested or compiled

ENUM_TIMEFRAMES Pause=PERIOD_M1; //Assuming you want to pause for a minute
static datetime past = 0;
datetime current = iTime(NULL,0.0);
if(ipast<current) {
          // time to pause
   past= current+PeriodSeconds(Pause);
  }
 

@Camilo Mora & @Arpit T — Do you not realise there is a reason why you should not use Sleep or any other delaying function?

If you cause a delay, you hold up the thread which is shared among the chart and all indicators on it, and they will ALL freeze, including the chart!

  • The Sleep() function can't be called for custom indicators, because indicators are executed in the interface thread and must not slow down it. The function has the built-in check of EA halt flag every 0.1 seconds.

That is not how you design an indicator. You cannot use delays. You have to use an event driven architecture with state machines (saved states).

Just as @Dominik Egert has explained, a solution can only be given once we understand what it is that @Anas Morad is trying to achieve. There is no generic way to approach the issue.

 

well, as I mentioned, and as you see from the code, I am trying to perform a simple CopyTime operation (for some reason it fails very often at the first tries, even after synchronizing the needed history with CheckLoadHistory()). if it fails, I want to wait some time and repeat the process until success, after that continue with my calculations for my custom indicator.

Maybe my Sleep() approach wasn't correct as mentioned by Fernando. And it is not my aim to stop the indicator and the charts until function succeeds. But also, I don't want to wait for the next tick (OnCalculate), as the indicator should work even if the market is closed. So I was thinking of some way to keep repeating the calculations after a while until succeed.

I think I will use a Timer, and put my calculations in the OnTimer function. I will kill the Timer after succeed. (??)

 
Anas Morad #:

well, as I mentioned, and as you see from the code, I am trying to perform a simple CopyTime operation (for some reason it fails very often at the first tries, even after synchronizing the needed history with CheckLoadHistory()). if it fails, I want to wait some time and repeat the process until success, after that continue with my calculations for my custom indicator.

Maybe my Sleep() approach wasn't correct as mentioned by Fernando. And it is not my aim to stop the indicator and the charts until function succeeds. But also, I don't want to wait for the next tick (OnCalculate), as the indicator should work even if the market is closed. So I was thinking of some way to keep repeating the calculations after a while until succeed.

I think I will use a Timer, and put my calculations in the OnTimer function. I will kill the Timer after succeed. (??)

I am inclined to believe that this may be a XY issue, and you may need to rethink your logic.

Certainly using OnTimer may be one such answer but I would suggest you consider re-analysing your approach.

Since we have no ideia but you are actually working on, we are not able to offer you a more concrete answer.

 
Anas Morad #:

well, as I mentioned, and as you see from the code, I am trying to perform a simple CopyTime operation (for some reason it fails very often at the first tries, even after synchronizing the needed history with CheckLoadHistory()). if it fails, I want to wait some time and repeat the process until success, after that continue with my calculations for my custom indicator.

Maybe my Sleep() approach wasn't correct as mentioned by Fernando. And it is not my aim to stop the indicator and the charts until function succeeds. But also, I don't want to wait for the next tick (OnCalculate), as the indicator should work even if the market is closed. So I was thinking of some way to keep repeating the calculations after a while until succeed.

I think I will use a Timer, and put my calculations in the OnTimer function. I will kill the Timer after succeed. (??)

Maybe this helps, as I assume, you try to get data from a "non-chart-symbol".

In OnInit add the desired symbol to marketwatch. Now check, if that helps.

If it doesn't, you could force it as follows:

Build an indicator that has a buffer in which it stores the times.

Now open the chart with that specific foreign symbol and inject the indicator into that chart.

Retrieve a handle to the injected indicator.

Now you can copy the data from the buffer of the indicator, it should be loaded and you should be able to get the data.

Though, I am not certain this will infact give you the data already in the first call to OnCalculate, but that would be anyways the best way I can think of to force load the data you require...

Beyond that, if that is still not enough, then it will get even more complicated.

What you could try to do now, in case it's not working, is to reload your main indicator from your "time-buffer-indicator" once it has loaded all data.

The problem you are facing is the off markets situation, and it's not easy to solve with conventional methods. You need some extras to make it work...
 
Dominik Egert #In OnInit add the desired symbol to marketwatch. Now check, if that helps.

It is my opinion that no attempt should be made during OnInit to pull data from the trade server for whatever reason, because there is no guarantee that during the OnInit there is even a connection to the server at all.

Imagine the case for when opening MetaTrader that was previously closed with an open chart with indicators on it. As the terminal starts up, the chart opens and the indicators initialise, but the connection to the trade server may not yet be up.

Reason: