Limiting the number of trades placed by your Expert Advisor using MQL4
Michael Pogson - MyForexResults.com
One of the most common problems with Expert Advisors (EAs) is that they do not have a mechanism of limiting how many trades they can place in any one timeframe. This may not sound like a big problem, but consider this scenario. Your EA is working on the daily timeframe. It opens a position at 08:00 and gets stopped out at 09:10. The price then returns to the target opening price and your EA opens the position again. The price once again moves against you and hits your stoploss, resulting in two losing trades in as many hours. To your horror the price returns to the target open price and the EA opens yet another trade. This time, you think, the price must go the other way. But no, it hits your stoploss again, resulting in three losing trades. You get the picture.
In particularly choppy conditions there is nothing to suggest that this couldn't be repeated all day long, potentially wiping out your account. Therefore, it is imperative that you code your EA to allow you to restrict how many trades it can place in the same timeframe, and that is what this article will show you how to do.
This is, in fact, a very simple operation. There are really only three parts to it.
- 1. Define a global variable to store the status of trading.
- 2. Set the variable on placing a trade.
- 3. Reset the variable at the end of our chosen timeframe.
First we decide on a name for our global variable
and declare it at the top of our code. Remember that
this will be visible to any other mql4 programs you are
running from the same client terminal, so don't
name it the same as another global variable you are
already using! Next we need to set our global variable
at the beginning of each new time block that we enter.
For example, if you are wanting to limit the number of
trades placed during one day and you are running your
program on a daily chart, each day is represented by
one bar. Therefore, you can determine if you are in a
new time block (day) by seeing if the number of bars on
your chart has increased by using the 'Bars'
function (a new day means a new bar on your chart). If
you are, then reset your global variable to
false:-
string hasOrderedGV = "has_ordered_GV"; string barsGV = "bars_GV"; int start(){ if ((GlobalVariableGet(barsGV) == 0)||(GlobalVariableGet(barsGV) < Bars)){ GlobalVariableSet(hasOrderedGV,false); GlobalVariableSet(barsGV,Bars); } // more code to go here return(0); }
You will notice that we have also used global variables to store the number of bars on our chart, and set it with the new number of bars on our chart each time a new bar is formed. This is one way of determining a given time block and as long as you don't want to use a time block other than the timeframe being used on the chart that you are using, it works very well. The next step is to check if we can order based on the value of our global variable. If it is false (we haven't placed an order yet in this time block) then we can proceed. Otherwise we cannot place an order:-
string hasOrderedGV = "has_ordered_GV"; string barsGV = "bars_GV"; int start(){ if ((GlobalVariableGet(barsGV) == 0)||(GlobalVariableGet(barsGV) < Bars)){ GlobalVariableSet(hasOrderedGV,false); GlobalVariableSet(barsGV,Bars); } if(GlobalVariableGet(hasOrderedGV,false)){ //more code to go here } } return(0); }
Now, assuming that we were allowed to place an order and our order executed successfully, then we must set our global variable to true to prevent another order being opened during this time block:-
string hasOrderedGV = "has_ordered_GV"; string barsGV = "bars_GV"; int start(){ if ((GlobalVariableGet(barsGV) == 0)||(GlobalVariableGet(barsGV) < Bars)){ GlobalVariableSet(hasOrderedGV,false); GlobalVariableSet(barsGV,Bars); } if(GlobalVariableGet(hasOrderedGV,false)){ if(conditions to be met for an order to be place){ //code to place your order goes here if(your order was successfully executed){ GlobalVariableSet(hasOrderedGV,true); }else{ Print("Error opening order : ",GetLastError()); } } } return(0); }
And there you have it. This should stop any more than one order per time block being placed. At the end of the time block, the code will reset the global variable to false, allowing orders to be placed during the next time block. Note that for the sake of simplicity, this has been described only for buy orders. You can do exactly the same for sell orders assuming you only want one order (buy or sell) to be placed per time block. If you want only one buy order AND only one sell order per time block, you simply need to create a global variable for the buy order and a global variable for the sell order, name them something appropriate ("hasOrderedShort", "hasOrderedLong" for example), and set the appropriate one when an order has been successfully placed. Don't forget to reset BOTH of them to false at the beginning of your new time block.
Log in to post comments
