A Pause between Trades
1. A Must or a Goodwill?
In the МetaТrader 3 Client Terminal, it was impossible to perform 2 trades at an interval under 10 seconds. Developing its МТ4, the MetaQuotes Software Corporation met the wishes of traders to remove this limitation. Indeed, there are situations where it is quite acceptable to perform a number of trades one after another (moving of StopLoss levels for several positions, removing of pending orders, etc.). But some traders took it in a wrong way and set about writing "killer" experts that could open positions one-by-one without a break. This resulted in blocked accounts or, at least, in the broker's unfriendly attitude.
This article is not for the above writers. It is for those who would like to make their trading comfortable for both themselves and their broker.
2. One Expert or Several Experts: What Is the Difference?
If you have only one terminal launched and only one expert working on it, it is simplicity itself to arrange a pause between trades: it is sufficient to create a global variable (a variable declared at global level, not to be confused with the terminal's Global Variables) and store the time for the last operation in it. And, of course, you should check before performing of each trade operation, whether the time elapsed after the last attempt to trade is sufficient.
This will look like this:
datetime LastTradeTime = 0; int start() { // check whether we should enter the market ... // calculate the levels of StopLoss and TakeProfit and the lot size ... // check whether sufficient time has elapsed after the last trade if(LocalTime() - LastTradeTime < 10) { Comment("Less than 10 seconds have elapsed after the last trade!", " The expert won't trade!"); return(-1); } // open a position if(OrderSend(...) < 0) { Alert( "Error opening position # ", GetLastError() ); return(-2); } // memorize the time of the last trade LastTradeTime = LocalTime(); return(0); }
This example is suitable for one expert working on one terminal. If one or several more experts are launched simultaneously, they will not keep the 10-second pause. They will not just be aware of when another expert was trading. Every expert will have its own, local LastTradeTime variable. The way out of this is obvious: You should create a Global Variable and store the time of the trade in it. Here we mean the terminal's Global Variable, all experts will be able to access to it.
3. The _PauseBeforeTrade() Function
Since the code realizing the pause will be the same for all experts, it will be more reasonable to arrange it as a function. This will provide maximum usability and minimum volume of the expert code.
Prior to writing the code, let as define our task more concretely - this will save our time and efforts. Thus, this is what the function must do:
- check whether a global variable has been created and, if not, create it. It would be more logical and saving to do it from the expert's init() function, but then the would be a probability that the user will delete it and all experts working at the time will stop keeping the pause between trades. So we will place it in the function to be created;
- memorize the current time in the global variable in order for other experts to keep the pause;
- check whether enough time has elapsed after the last trade. For usability, it is also necessary to add an external variable that would set the necessary duration of the pause. Its value can be changed for each expert separately;
- display information about the process and about all the errors occurred during the work;
- return different values depending on the performance results.
If the function detects that not enough time has elapsed after the last trade, it must wait. The Sleep() function will provide both waiting and checking of the IsStopped(). I.e., if you delete the expert from the chart during it "sleeps", it will not hang up or be stopped forcedly.
But, for more self-descriptiveness, let us (every second during the "sleep") display information about how long it still remains to wait.
This is what we have to get as a result:
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; } } } }
4. Integration into Experts and How to Use It
To check operability of the function, we created a diagnostic expert that had to trade keeping pauses between trades. The _PauseBeforeTrade() function was preliminarily placed into the PauseBeforeTrade.mq4 file included into the expert using the #include directive.
Attention! This expert is only dedicated for checking the function operability! It may not be used for trading!
#include <PauseBeforeTrade.mq4> int ticket = 0; int start() { // if there is no position opened by this expert if(ticket <= 0) { // keep a pause between trades, if an error has occurred, exit if(_PauseBeforeTrade() < 0) return(-1); // update the market information RefreshRates(); // and try to open a position ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 5, 0.0, 0.0, "PauseTest", 123, 0, Lime); if(ticket < 0) Alert("Error OrderSend № ", GetLastError()); } // if there is a position opened by this expert else { // keep the pause between trades (if an error has occurred, exit) if(_PauseBeforeTrade() < 0) return(-1); // update the market information RefreshRates(); // and try to close the position if (!OrderClose( ticket, 0.1, Bid, 5, Lime )) Alert("Error OrderClose № ", GetLastError()); else ticket = 0; } return(0); }
After that, one expert was attached to the EURUSD-M1 chart and another one, absolutely identical, to the GBPUSD-M1 chart. The result did not keep one waiting long: Both experts started trading keeping the prescribed 10-second pause between trades:
5. Possible Problems
When several experts work with one global variable, error can occur. To avoid this, we must delimit access to the variable. A working algorithm of such "delimitation" is described in details in the article named "Error 146 ("Trade context busy") and How to Deal with It". It is this algorithm that we will use.
The final version of the expert will look like this:
#include <PauseBeforeTrade.mq4> #include <TradeContext.mq4> int ticket = 0; int start() { // if there is no a position opened by this expert if(ticket <= 0) { // wait until the trade is not busy and occupy it (if an error has occurred, // exit) if(TradeIsBusy() < 0) return(-1); // keep the pause between trades if(_PauseBeforeTrade() < 0) { // if an error has occurred, free the trade and exit TradeIsNotBusy(); return(-1); } // update the market information RefreshRates(); // and try to open a position ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 5, 0.0, 0.0, "PauseTest", 123, 0, Lime); if (ticket < 0) Alert("Error OrderSend № ", GetLastError()); // free the trade TradeIsNotBusy(); } // if there is a position opened by this expert else { // wait until the trade is not busy and occupy it (if an error has occurred, // exit) if(TradeIsBusy() < 0) return(-1); // keep the pause between trades if(_PauseBeforeTrade() < 0) { // if an error occurs, free the trade and exit TradeIsNotBusy(); return(-1); } // update the market information RefreshRates(); // and try to close the position if(!OrderClose( ticket, 0.1, Bid, 5, Lime)) Alert("Error OrderClose № ", GetLastError()); else ticket = 0; // free the trade TradeIsNotBusy(); } return(0); }
Translated from Russian by MetaQuotes Ltd.
Original article: https://www.mql5.com/ru/articles/1355
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
How to install this
The article was written 14 years ago. You don't need this pause in 2020.
The article was written 14 years ago. You don't need this pause in 2020.
Why not?
Because MT server can accept a lot of orders every second.
If you need implement pause to your trading algorithm, it is not hard. But you don't need this article.
Because MT server can accept a lot of orders every second.
If you need implement pause to your trading algorithm, it is not hard. But you don't need this article.
How can we implement this pause pls
You don't need this pause nowadays.