Sleep function in backtest

 

hello mql community,

i'm lucky to be a part of this community. mql is the first programming language that makes sense. :-)

but i've a problem: it seems so that the sleep function doesn't work in backtest. is that right? is there a solution for that?


best regards, derox

 

Sleep() is 'skipped' in the Tester. From the article 'Testing Features and Limits in MetaTrader 4':

Some functions are processed/passed without output

These are Sleep(), Alert(), SendMail(), PlaySound(), MessageBox(), WindowFind(), WindowHandle(), WindowIsVisible()

Technically it's impossible to simulate Sleep(), since the Tester's time is quantized as opposed to being continuous (as in Live/Demo). U can simulate Sleep() to some degree by skipping ticks, but that only enables sleeping the amount of time between ticks. That time is determined by the specific bar's volume value, since the Tester produces as many ticks in a bar as the volume in that bar (in 'Every Tick' mode).

So for example if you are Testing on M1 and a certain bar has a volume of 20, u will only be able to skip 60/20=3 sec at a time, so u will only be able to simulate sleeping for 3 secs. Depending on what u are trying to achieve this might be good enough for u.

As to how to technically do it:

int start()
{
   static int wait = 0;
   if ( ... )                             // condition for sleeping
      wait = TimeCurrent() + 5;           // sleeping for at least 5 seconds
   if ( TimeCurrent() < wait )            
      return(0);                          // skiping to next tick

   // main program code here...
   
   return(0);
}

Note that this will make it "sleep" for at least 5 seconds (but maybe much more than that)... Also, the following will NOT work in the Tester (although it will work in Live/Demo):

int start()
{
   int wait = 0;
   if ( ... )                              // condition for sleeping
      wait = TimeCurrent() + 5;            // sleeping for at least 5 seconds
   while ( TimeCurrent() < wait ) {}       // this will NOT work in the Tester, it would cause it to loop endlessly...

   // main program code here...
   
   return(0);
}
 
There is an article about the pros and cons of sleeping here -> https://www.mql5.com/en/articles/1558.
 
gordon:
There is an article about the pros and cons of sleeping here -> https://www.mql5.com/en/articles/1558.

thanks gordon for your answer. the problem is that the signal for opening a trade is still valid if the expert hits the take profit. result is he open another position, but the signal is weak at this time. i can filter this trades manually, but it takes time. i thought there was an easy way. ;-p thank you very much for your help.
 
gordon:

Sleep() is 'skipped' in the Tester. From the article 'Testing Features and Limits in MetaTrader 4':

Technically it's impossible to simulate Sleep(), since the Tester's time is quantized as opposed to being continuous (as in Live/Demo). U can simulate Sleep() to some degree by skipping ticks, but that only enables sleeping the amount of time between ticks. That time is determined by the specific bar's volume value, since the Tester produces as many ticks in a bar as the volume in that bar (in 'Every Tick' mode).

So for example if you are Testing on M1 and a certain bar has a volume of 20, u will only be able to skip 60/20=3 sec at a time, so u will only be able to simulate sleeping for 3 secs. Depending on what u are trying to achieve this might be good enough for u.

As to how to technically do it:

Note that this will make it "sleep" for at least 5 seconds (but maybe much more than that)... Also, the following will NOT work in the Tester (although it will work in Live/Demo):

Thanks! You answered my question about why my EA got stuck in an endless loop, when it tries using TimeCurrent to try to break-out.

But then how do I know my code will work (in backtest) before putting it into demo? I'm trying to create a loop to retry trading commands (OrderSend, OrderClose) until a timeout is hit. When the timeout is hit, the code should give up and start() fn exits until the next tick.

 
actually, the suggested method of using timecurrent() and adding a wait time does works, if you code it out logically in your EA, i use that all the time to beat the sleep() issue i need in backtest...and live as well.
 
senshine:
actually, the suggested method of using timecurrent() and adding a wait time does works, if you code it out logically in your EA, i use that all the time to beat the sleep() issue i need in backtest...and live as well.
Reread the code. He didn't use a test of TimeCurrent() and return. he used a loop, which will NEVER work in the tester.
 

This is an old thread. I'm just adding a code hoping that this will help someone.

The Sleep() function do not work during Backtesting as it is automatically skipped. I use this custom sbSleepForMS() routine in place of the standard Sleep() function. This sbSleepForMS() will sleep for x milliseconds regardless of whichever mode it is in (Live or Backtest). It works for me,

void sbSleepForMS( int pviSleepForMS ) {
        //This is a Sleep() function designed to work on either LIVE mode or BACKTEST mode.
        // The built-in Sleep() function is skipped by MQL4 during Backtesting, thus another
        // way to simulate the Sleep() function is required. We will use a while loop for it.

        if( !IsTesting() )
                Sleep(pviSleepForMS);
        else {
                //This section uses a while loop to simulate Sleep() during Backtest.
                int viSleepUntilTick    = GetTickCount() + pviSleepForMS;
                while( GetTickCount() < viSleepUntilTick ) {
                        //Do absolutely nothing. Just loop until the desired tick is reached.
                }
        }
}
 
fhlee74:

This is an old thread. I'm just adding a code hoping that this will help someone.

The Sleep() function do not work during Backtesting as it is automatically skipped. I use this custom sbSleepForMS() routine in place of the standard Sleep() function. This sbSleepForMS() will sleep for x milliseconds regardless of whichever mode it is in (Live or Backtest). It works for me,

If you understood how the Strategy Tester worked you would understand why sleep() in the Strategy Tester makes absolutely no logical sense . . .
 
And why your sbSleepForMS() will only slow down your optimization but do nothing else.
 

I do not know why others would need it. But for me:

- I uses it during VISUAL MODE. When some condition happen during backtest, I would like the process to be "slowed down" or "paused" so I can check some of the params and conditions. This is probably during development/debug stage.

- Another time when I use it is also with VISUAL MODE, when I want to make a video of how the EA works, I will put the sbSleepForMS() when my EA opens/closes trades. I will then set the backtest to run fastest.
This way, when my video plays, or when I want to show people the EA "in action", it will skip all the boring parts (will zoom past with the fastest speed) and when my EA opens/closes orders, it will slow down during those times. This will create a more "visually appealing" playback.