Help with pause between EAs

 

Hi,

I was wondering if there is a simple way to have a global pause of 5 seconds between trade actions across 3 EAs? Any help would be greatly appreciated, I'm stumped. 

I can't seem to get this example to work: https://www.mql5.com/en/articles/1355

A Pause between Trades
A Pause between Trades
  • 2006.08.08
  • Andrey Khatimlianskii
  • www.mql5.com
The article deals with the problem of how to arrange pauses between trade operations when a number of experts work on one МТ 4 Client Terminal. It is intended for users who have basic skills in both working with the terminal and programming in MQL 4.
 
If the article describes what you need, which errors do you get exactly?
 

"Event Handling Function Not Found" is the error I get from  PauseBeforeTrade.mq4, If I try and fix it I get more problems. I was also wondering if all this code is necessary?  This should work for my needs, but I've never made my functions external before.


extern int PauseBeforeTrade = 10; // pause between trades (in seconds)
 
/////////////////////////////////////////////////////////////////////////////////
// int _PauseBeforeTrade()
//
// The function sets the local time value for the global variable LastTradeTime.
// If the local time value at the moment of launch is less than LastTradeTime + 
// PauseBeforeTrade value, the function will wait.
// If there is no global variable LastTradeTime at all, the function will create it.
// Return codes:
//  1 - successful completion
// -1 - the expert was interrupted by the user (the expert was deleted from the chart, 
//      the terminal was closed, the chart symbol or period was changed, etc.)
/////////////////////////////////////////////////////////////////////////////////
int _PauseBeforeTrade()
 {
  // there is no reason to keep the pause during testing - just terminate the function
  if(IsTesting()) 
    return(1); 
  int _GetLastError = 0;
  int _LastTradeTime, RealPauseBeforeTrade;
 
  //+------------------------------------------------------------------+
  //| Check whether the global variable exists and, if not, create it  |
  //+------------------------------------------------------------------+
  while(true)
   {
    // if the expert was interrupted by the user, stop working
    if(IsStopped()) 
     { 
      Print("The expert was stopped by the user!"); 
      return(-1); 
     }
    // check whether a global variable exists
    // if yes, exit this loop
    if(GlobalVariableCheck("LastTradeTime")) 
      break;
    else
     // if the GlobalVariableCheck returns FALSE, it means that either global variable does not exist, or 
     // an error occurred during checking
     {
      _GetLastError = GetLastError();
      // if it is still an error, display information, wait during 0.1 sec, and start to 
      // recheck
      if(_GetLastError != 0)
       {
        Print("_PauseBeforeTrade()-GlobalVariableCheck(\"LastTradeTime\")-Error #",
              _GetLastError );
        Sleep(100);
        continue;
       }
     }
    // if no error occurs, it just means that there is no global variable, try to create it
    // if GlobalVariableSet > 0, it means that the global variable has been successfully created. 
    // Exit the function
    if(GlobalVariableSet("LastTradeTime", LocalTime() ) > 0) 
      return(1);
    else
     // if GlobalVariableSet returns a value <= 0, it means that an error occurred during creation 
     // of the variable
     {
      _GetLastError = GetLastError();
      // display information, wait 0.1 sec, and restart the attempt 
      if(_GetLastError != 0)
       {
        Print("_PauseBeforeTrade()-GlobalVariableSet(\"LastTradeTime\", ", 
              LocalTime(), ") - Error #", _GetLastError );
        Sleep(100);
        continue;
       }
     }
   }
  //+--------------------------------------------------------------------------------+
  //| If the function performance has reached this point, it means that the global   |
  //| variable exists.                                                                    |
  //| Wait until LocalTime() becomes > LastTradeTime + PauseBeforeTrade               |
  //+--------------------------------------------------------------------------------+
  while(true)
   {
    // if the expert was stopped by the user, stop working
    if(IsStopped()) 
     { 
      Print("The expert was stopped by the user!"); 
      return(-1); 
     }
    // get the value of the global variable
    _LastTradeTime = GlobalVariableGet("LastTradeTime");
    // if an error occurs at this, display information, wait 0.1 sec, and try 
    // again
    _GetLastError = GetLastError();
    if(_GetLastError != 0)
     {
      Print("_PauseBeforeTrade()-GlobalVariableGet(\"LastTradeTime\")-Error #", 
            _GetLastError );
      continue;
     }
    // count how many seconds have been elapsed since the last trade
    RealPauseBeforeTrade = LocalTime() - _LastTradeTime;
    // if less than PauseBeforeTrade seconds have elapsed,
    if(RealPauseBeforeTrade < PauseBeforeTrade)
     {
      // display information, wait one second, and check again
      Comment("Pause between trades. Remaining time: ", 
               PauseBeforeTrade - RealPauseBeforeTrade, " sec" );
      Sleep(1000);
      continue;
     }
    // if the time elapsed exceeds PauseBeforeTrade seconds, stop the loop
    else
      break;
   }
  //+--------------------------------------------------------------------------------+
  //| If the function performance has reached this point, it means that the global   |
  //| variable exists and the local time exceeds LastTradeTime + PauseBeforeTrade    |
  //| Set the local time value for the global variable LastTradeTime                 |
  //+--------------------------------------------------------------------------------+
  while(true)
   {
    // if the expert was stopped by the user, stop working
    if(IsStopped()) 
     { 
      Print("The expert was stopped by the user!"); 
      return(-1);
     }

    // Set the local time value for the global variable LastTradeTime.
    // In case it succeeds - exit
    if(GlobalVariableSet( "LastTradeTime", LocalTime() ) > 0) 
     { 
      Comment(""); 
      return(1); 
     }
    else
    // if the GlobalVariableSet returns a value <= 0, it means that an error occurred
     {
      _GetLastError = GetLastError();
      // display the information, wait 0.1 sec, and restart attempt
      if(_GetLastError != 0)
       {
        Print("_PauseBeforeTrade()-GlobalVariableSet(\"LastTradeTime\", ", 
              LocalTime(), " ) - Error #", _GetLastError );
        Sleep(100);
        continue;
       }
     }
   }
 }
 
Jesse Phipps:

"Event Handling Function Not Found" is the error I get from  PauseBeforeTrade.mq4, If I try and fix it I get more problems. I was also wondering if all this code is necessary?  This should work for my needs, but I've never made my functions external before.



You're missing the OnTick()... 

You could also do something simple in each EA like this.

string global_waiting_var_name = "waiting_period";
void OnTick()
{
   if(IsWaitingPeriod())
      return;
}
bool SetWaitingPeriod(int seconds)
{
   return (GlobalVariableSet(global_waiting_var_name,double(TimeCurrent()+seconds)) > 0);
}
bool IsWaitingPeriod()
{
   if(!GlobalVariableCheck(global_waiting_var_name))
      return false;
   return (TimeCurrent() > (datetime)GlobalVariableGet(global_waiting_var_name));
}
 
nicholishen:

Forum on trading, automated trading systems and testing trading strategies

Help with pause between EAs

nicholishen, 2017.08.20 04:35


You're missing the OnTick()... 

You could also do something simple in each EA like this.

string global_waiting_var_name = "waiting_period";
void OnTick()
{
   if(IsWaitingPeriod())
      return;
}
bool SetWaitingPeriod(int seconds)
{
   return (GlobalVariableSet(global_waiting_var_name,double(TimeCurrent()+seconds)) > 0);
}
bool IsWaitingPeriod()
{
   if(!GlobalVariableCheck(global_waiting_var_name))
      return false;
   return (TimeCurrent() > (datetime)GlobalVariableGet(global_waiting_var_name));
}


I think IsWaitingPeriod() has wrong comparison - currently it returns true (waiting period is active) when current time is larger than the limit in the global variable, and bypasses waiting (returns false) when current time is less than or equal to the limit.

Also I believe that SetWaitingPeriod can not set global variable unconditionally and should check if it's already in a waiting state, because otherwise you'll update the limit and may never start operation.

 
Stanislav Korotky:

I think IsWaitingPeriod() has wrong comparison - currently it returns true (waiting period is active) when current time is larger than the limit in the global variable, and bypasses waiting (returns false) when current time is less than or equal to the limit.

Also I believe that SetWaitingPeriod can not set global variable unconditionally and should check if it's already in a waiting state, because otherwise you'll update the limit and may never start operation.


Good catch, is typo... Should be

return (TimeCurrent() < (datetime)GlobalVariableGet(global_waiting_var_name));


Theoretically speaking, how would the waiting period be set whilst in the waiting period? The code would never reach that point of execution so the check would be redundant and unnecessary. Also GlobalVariableSet creates a variable if it doesn't already exist so again checking that would also be redundant and unnecessary. 

 
nicholishen:

Theoretically speaking, how would the waiting period be set whilst in the waiting period? The code would never reach that point of execution so the check would be redundant and unnecessary. Also GlobalVariableSet creates a variable if it doesn't already exist so again checking that would also be redundant and unnecessary. 

Which part of the code does guarantee that setting the global variable is prevented while it contains a time limit which is not yet exceeded? I don't see this part in the example, so "that point of execution" is perfectly reachable (do you remember we have 3 EAs?). Anyway, any function should take care of proper execution and check if all preconditions are met, because the function itself can not guarantee that it will be always called properly. I'd say the check-up is really necessary, and moreover there must be one more global variable to simulate a mutex in your code. Each EA is running in a separate thread, and can interfere with each other while operating on the global variable you suggested. Just imagine that one EA calls IsWaitingPeriod and gets false, and another EA calls it in parallel with the same result - then both starts trading simultaneously. This is why I'd personally recommend to use the code from the article. It's free from this problem.

BTW, what does seem redundant is the call to GlobalVariableCheck, because the shortened:

bool IsWaitingPeriod()
{
  return(TimeCurrent() < (datetime)GlobalVariableGet(global_waiting_var_name));
}

will do the job as well.