Let's trade using computer science!

Hi fellow traders!

One of the most frequently asked questions I get from my blog readers is how to handle market spread when opening new orders using MetaTrader platform. So in this section I will try to illustrate how I handle Spread vs Stop Loss and Take Profit levels. So let’s first look in the MQL4 manual (MQL4 is the programming language of MT4).

Source: https://docs.mql4.com/trading/ordersend ordersend with stoploss

In the example above a ‘Buy’ order is opened at ‘Ask’ price, with a StopLoss and TakeProfit levels equal to minimum allowed StopLoss distance from the current ‘Bid’ price. Using the ‘Bid’ price as reference for SL/TP levels, is the recommended way of opening orders, but is this really the best way?..So it depends on your risk-reward ratio. Most of my own trading systems require a risk-reward of 1:1, so for example: StopLoss = 10 Pips and TakeProfit = 10 Pips. Let’s see what would happen if I have followed recommendation from the MT4 manual and used ‘Bid’ price as reference point for my TP and SL levels: In this configuration, with assumed spread of 2 Pips, my EA would make only 8 Pips hitting profit and would loss 12 Pips when hitting my StopLoss level. If my trading system had a 50% winning ratio I would be only losing my money!

So how to deal with spread when opening new market positions?


The answer is very simple: Always use your entry price as SL and TP reference. This means using ‘Ask’ for Buy orders and ‘Bid’ levels for ‘Sell’ orders. In this configuration the EA will always win and lose the same amount of money. Using this approach you need only a winning ratio of 51% in order to be profitable on the long term. (this of course not including slippages and broker commissions).

However, there is a big ‘BUT’ for this strategy! You should avoid spread widening, which can be introduced by your broker e.g.: during high volatile events like market news release. The code below show how to avoid spread widening and how to set SL and TP using entry levels.


bool OpenBuy()
{
   //Get new market prices
   RefreshRates();
   
   //Define lot size
   double Lots = 0.1;
   int LotDigits = (int) - MathLog10(SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP));
   double LotSize=NormalizeDouble(Lots,LotDigits); 
   
   //Calculate and check spread  
   double MaxSpreadInPoints = 50; 
   double Spread = Ask - Bid;
   if(Spread>MaxSpreadInPoints*Point)
      return(false);
   
   //Define allowed slippage
   int SlippageInPoints = 20;
   
   //Define TakeProfit and StopLoss levels 
   double TakeProfit = NormalizeDouble(Bid+Spread+10*PIP,Digits);
   double StopLoss = NormalizeDouble(Bid+Spread-10*PIP,Digits);;

   Ticket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,SlippageInPoints,StopLoss,TakeProfit,"Spread Test",MagicNr,0,Green);
   
   if(Ticket==-1)
   {
      Alert("Buy Error: " ,GetLastError());
      return(false); 
   }
   if(Ticket>=0)
   {
      return(true);
   }
   
   return(false);
}

bool OpenSell()
{
   //Get new market prices
   RefreshRates();
   
   //Define lot size
   double Lots = 0.1;
   int LotDigits = (int) - MathLog10(SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP));
   double LotSize=NormalizeDouble(Lots,LotDigits); 
   
   //Calculate and check spread  
   double MaxSpreadInPoints = 50; 
   double Spread = Ask - Bid;
   if(Spread>MaxSpreadInPoints*Point)
      return(false);
   
   //Define allowed slippage
   int SlippageInPoints = 20;
   
   //Define TakeProfit and StopLoss levels 
   double TakeProfit = NormalizeDouble(Bid-10*PIP,Digits);
   double StopLoss = NormalizeDouble(Bid+10*PIP,Digits);;

   Ticket=OrderSend(Symbol(),OP_SELL,LotSize,Bid,SlippageInPoints,StopLoss,TakeProfit,"Spread Test",MagicNr,0,Red);
   
   if(Ticket==-1)
   {
      Alert("Sell Error: " ,GetLastError());
      return(false); 
   }
   if(Ticket>=0)
   {
      return(true);
   }
   
   return(false);
}	

As you can see only 'Buy' orders need an additional entry level correction, since 'Sell' orders are using 'Bid' as entry price. The following figure shows the outcome of this approach: 1:1 risk-reward example
The EA based on this strategy always wins and losses equal amount of money, which in this example is equal to $10.

That's it;)
Greets,
Chris

Short about me

Welcome to my Blog!

My name is Chris, I'm an engineer, system trader and internet entrepreneur. I hope you will enjoy my website and my free MT4 software. Do not forget to check out my blog and our forum.
B.t.w: 'coensio' (Latin) = assessing, assessment, census, estimating, opinion, rating, taxing.

Get free coensio strategies!
StrategyQuant with discount!
My newsletter

Subscribe to my newsletter