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.
I choose to use a global variable here as it allows us to store the status of whether we are allowed to place another trade or not, even if the system is temporarily shutdown and restarted for some reason. Note: global variables are different entities to variables that are declared within the global scope of an mql4 program. They are accessible by all mql4 programs within the same client terminal and are stored for 4 weeks since the last access before being deleted automatically.

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

Share |