How To Code Trailing Stop Loss In MQL5?

Stop loss is very important in a trade. But there are professional traders who don’t use stop loss. You can also watch this video in which a millionaire forex trader explains why I don’t use a stop loss. I use a stop loss and I highly recommend that you also use a stop loss. As a trader your primary goal is to minimize risk as much as possible while at the same time you need to maximize profit. When you are trading, go for high reward and low risk trades. I usually look for trades that have a small stop loss like 10-20 pips and a profit target of 100-200 pips. Over the years, I have learned that it is very much possible to reduce risk to as low as 10-20 pips. When I started I would happily open a trade with a stop loss of 50 pips. But now I consider 50 pips to be too risky.  I am even reluctant to open a trade with a stop loss of 20 pips. I am happy with a small stop loss of 10-15 pips. When you start it would be difficult to reach this level of perfection. For example in the start if you have a strategy that makes 50 pips with a stop loss of 50 pips, you should try to increase the profit to 100 pips while decreasing the risk to 20 pips. Can you do it? It all depends on the tools that you employ. One of the tools that can help you achieve that is the trailing stop loss.

Have you ever tried to trade US Presidential Elections? Read this post in which I show how to trade US Presidential Elections. The only problem: you can trade US Presidential Elections once in 4 years. Below is a screenshot of what happened in the recent US Presidential Elections. Market sentiment changes with the voter sentiment. Markets are highly emotional now a days. You should know this fact. Modern markets are news driven. Forget the fundamentals in the short run. In the screenshot below, you can see when the news of Donald Trump winning US Presidential Elections broke market reacted negatively and USDJPY started falling sharply.

How To Trade US Presidential Elections

After a few hours, market changed its mind. After all Donald Trump winning US Presidential Elections was not bad for US economy. USDJPY started rallying. You can see that in the image below. A strong rally has started. Interesting this Dollar rally continued for a few weeks. So you can see how much sentimental markets are now a days. When you develop trading strategies, you should keep this fact in your mind. All we have the price action. That’s all!

How To Trade US Presidential Elections

A trailing stop loss always trails the price as the name implies. This is how the trailing stop loss works. When you place in a buy order, a trailing stop loss will follow the price upward keeping a safe distance from it. We will specify the safe distance. In the same manner, when we have a sell order, a trailing stop loss will follow the price downward keeping a safe distance from it. Most of the time we fix safe distance as 50 pips. We need to give the price some space to breath. This safe distance is the trailing stop loss. 50 pips trailing stop loss means that our stop loss will trailing price with a minimum distance of 50 pips. We can delay the trailing stop loss kicking in by requiring that a minimum profit level be reached before it starts trailing the price. So unlike a fixed stop loss, a trailing stop loss follows the price. This provides us with opportunities as well as  Too tight a trailing stop loss and we will be out of action pretty soon. We want to catch the price movement as much as possible so as to maximize our profits. Never coded before? Don’t worry. MQL5 is an easy language. You just need a little effort to learn it. Read this post on how to code an EA to trade price action with 2 EMAs. Now coming back to our trailing stop loss. The important question is why you need to code an EA. EA can help you a lot when the price moves rapidly. You cannot close the trade manually as fast as an EA can. So let’s add a simple trailing stop loss to our expert advisor:

// define the input variables
// we define the trailing stop loss to be 30 pips
input int trailingSL = 300;
// OnTick() event handler
//check if a position is already open on the chart
//if we have an open position and the trailing stop loss is greater than zero we proceed further
if(PositionSelect(_Symbol) == true && trailingSL > 0)
{
//inform the trade server that we want to modify stop loss and take profit 
       request.action = TRADE_ACTION_SLTP;
       request.symbol = _Symbol;
//get the position type from the trade server
       long positionType = PositionGetInteger(POSITION_TYPE);
//get the current stop loss from the trade server
       double currentSL = PositionGetDouble(POSITION_SL);
//convert the trailingSL into price increment
       double trailSL = trailingSL * _Point;
       double trailingStopPrice;
//check if we have a buy trade
       if(positionType == POSITION_TYPE_BUY)
         {
//for a buy trade we will subtract the trailSL from bid price
            trailingStopPrice = SymbolInfoDouble(_Symbol,SYMBOL_BID) - trailSL;

       if(trailingStopPrice > currentSL)
         {
            request.sl = trailingStopPrice;
            OrderSend(request,result);
         }
}
//check if we have a sell trade
     else if(positionType == POSITION_TYPE_SELL)
      {
//for a sell trade we will add the trailSL to the ask price
      trailingStopPrice = SymbolInfoDouble(_Symbol,SYMBOL_ASK) + trailSL;
      if(trailingStopPrice < currentSL)
      {
      request.sl = trailStopPrice;
      OrderSend(request,result);
      }
    }
}

Above we have defined a simple trailing stop loss for our expert advisor. First we define the trailing stop loss in points. I have defined it as 300 points or 30 pips. You can define trailing stop loss as 500 points or 50 pips or whatever you want. Over the years this is what I have learned. Keeping risk low is the strategy that will give you long term success. As I said in the beginning, your goal should be to make 100-200 pips with a small 10-20 pip stop loss. Next we move to the OnTick() event handler. The first thing that we do is check whether we have a position open on the chart or not. This code will only work for a single open position. This code is for educational purposes only.If we have an open position and the trailing stop loss is greater than zero than we proceed to second step in which we will change the stop loss if it is greater than the defined trailing stop loss. As we are using the OnTick() event handler, the code will be checked on each tick. If the conditions defined in the code are fulfilled, it will be executed instantly. Have you ever tried to trade naked? Read this post in which I explain how to trade naked. Watch the videos that explain how to identify the trend as a naked trader.

Now we use the MqlTradeRequest predefined structure. As we have an open position, we ask for request action TRADE_ACTION_SLTP. This informs the trade server that we want to modify the stop loss and the take profit levels. Then we tell the trade server that we will be using the current chart symbol with the request symbol.  We define the double variable trailSL in which we convert the trailingSL into price increment using the predefined _Point constant. Then we check if we have the POSITION_TYPE_BUY, we will subtract the trailSL from trailingStopPrice using the SymbolInfoDouble() function that gets the bid price for the current symbol for us. Next we check if the trailingStopLoss is greater than the current stop loss we tell the trade server to modify the stop loss. Trading news can be highly profitable if you know how to do it. Read this post in which I show how to trade NFP Report and make 150 pips with a small stop loss.

In the same manner, if we have a sell order open, we check for it wit POSITION_TYPE_SELL. If this is true, we calculate the trailingTopPrice using the SymbolInfoDouble() function by asking for the ask price and then adding the trailSL to it. We check if we have a trailingStopPrice less than currentSL we tell the trade server to modify the stop loss using the OrderSend() function. As said above, I have coded a simple trailing stop loss. In the code, we just check the bid/ask price and adjust the stop loss in accordance with our trailing stop loss. This way the stop loss trails the price keeping a safe distance from it. In our code, the safe distance is 30 pips. Now keep this in mind, price has the tendency to whipsaw. So it is very much possible that price retraces 30 pips hits the stop loss and starts moving back again. You should keep this in mind. This was a simple code. But keep this in mind. We will try to solve the problem of whipsaw so that we don’t get out of the trade too quickly while the price marches on.Trading exotic pairs like USDZAR can be a highly profitable idea. But you will need to aware of the economic situation in the country before you trade an exotic pair. Read this post in which I explain how to trade USDZAR pair.

How To Add A Minimum Profit?

We have a simple EA. We can now add more functionality to it. How about adding a minimum profit before our trailing stop loss gets activated. Taking some profit in each trade is a good strategy. You should ensure that you take profit no matter how much before the price starts reversing. Sometime waiting for the price to move up and hit your take profit target is not a good idea as price may never reach that level. Below I have added code to the above simple EA. This time we will ensure that there is a minimum profit before the trailing stop loss gets activated:

// define the input variables
//define the trailing stop loss
input int trailingSL = 500;
//define the minimum take profit target
input int minimumTP = 200;
// OnTick() event handler
//check if we have an open position
if(PositionSelect(_Symbol) == true && trailingSL > 0)
{
//tell the trade server we want to change the stop loss
     request.action = TRADE_ACTION_SLTP;
     request.symbol = _Symbol;
//get the position type, current stop loss and the entry price
     long positionType = PositionGetInteger(POSITION_TYPE);
     double currentSL = PositionGetDouble(POSITION_SL);
     double entryPrice = PositionGetDouble(POSITION_PRICE_OPEN);
// calculate the trailSL and minTP
     double minTP = minimumTP * _Point;
     double trailSL = trailingSL * _Point;
     double trailSP;
     double currentProfit;
//check if we have a buy trade open
       if(positionType == POSITION_TYPE_BUY)
     {
       trailSP = SymbolInfoDouble(_Symbol,SYMBOL_BID) - trailSL;
       currentProfit = SymbolInfoDouble(_Symbol,SYMBOL_BID) - entryPrice;
       if(trailSL > currentSL && currentProfit >= minTP)
     {
       request.sl = trailSL;
       OrderSend(request,result);
     }
     }

//check if we have a sell trade open
       else if(positionType == POSITION_TYPE_SELL)
     {
       trailSL = SymbolInfoDouble(_Symbol,SYMBOL_ASK) + trailSL;
       currentProfit = entryPrice – SymbolInfoDouble(_Symbol,SYMBOL_ASK);

    if(trailSL < currentSL && currentProfit >= minProfit)
     {
       request.sl = trailSL;
       OrderSend(request,result);
     }
   }
}

Above code is almost the same as the one for the simple expert advisor. The only addition that we have made is the minimumTP which we have set to 20 pips. This time we have the trailing stop loss set as 50 pips. This is done to provide price action with some breathing space. Just like before on each tick we check whether we have an open position. If we have an open position and the trailing stop loss is greater than zero we ask the trade server for the position type as well as the current stop loss. We also inform the trade server that we want to modify the stop loss of the open position. After that we get the POSITION_OPEN_PRICE and save it as entryPrice. We will calculate our current profit by subtracting the current price from the entry price. This is what we do when we calculate the profit. The rest of the code is almost same except that we have modified the if statement by adding one more condition. This time before we modify the current stop loss we need to check that both trailSL is greater than the currentSL as well as the currentProfit is greater than minTP. We calculate the current profit by subtracting the entry price from current price in case of a buy trade and subtracting current price from entry price in case of a sell trade. FOMC Meeting is very important for USD pairs. If we are trading with an EA, you should code it so that it does not trade during the time of FOMC Meeting Minutes release. Read this post in which I explain how you will trade FOMC Meeting.

When we code an EA, we can take many months. First we write code for a simple EA like that we did in the start. After that we keep on adding more functionality to our EA. With the passage of time we can have a pretty sophisticated EA. It is just like building a skyscraper. First you lay the foundations. Make sure you lay a solid foundation. If you have laid a solid foundation, you can build on it a skyscraper. Below we add more functionality to the trailing stop EA. This time we add a step value to the trailing stop loss EA.

// Input variables
input int trailingSL = 500;
input int minimumTP = 200;
input int stepSize = 10;
// OnTick() event handler

if(PositionSelect(_Symbol) == true && TrailingStop > 0)
{
         request.action = TRADE_ACTION_SLTP;
         request.symbol = _Symbol;
         long positionType = PositionGetInteger(POSITION_TYPE);
         double currentStop = PositionGetDouble(POSITION_SL);
         double entryPrice = PositionGetDouble(POSITION_PRICE_OPEN);
         double minTP = minimumTP * _Point;
    
    if(stepSize < 10) stepSize = 10; 
         double step = stepSize * _Point; 
         double trailSL = trailingSL * _Point; 
         double trailSP; 
         double currentProfit; 
    if(positionType == POSITION_TYPE_BUY) 
      { 
         trailSP = SymbolInfoDouble(_Symbol,SYMBOL_BID) - trailSL;
         currentProfit = SymbolInfoDouble(_Symbol,SYMBOL_BID) - entryPrice; 

    if(trailSP > currentStop + step && currentProfit >= minTP)
      {
         request.sl = trailSP;
         OrderSend(request,result);
      }
    }
    else if(posType == POSITION_TYPE_SELL)
     {
         trailSP = SymbolInfoDouble(_Symbol,SYMBOL_ASK) + trailStop;
         currentProfit = SymbolInfoDouble(_Symbol,SYMBOL_ASK) + entryPrice;

    if(trailSP < currentStop - step && currentProfit >= minTP)
      {
        request.sl = trailSP;
        OrderSend(request,result);
      }
   }
}

In the above code, we have defined a minimum step size. This ensures that the trailing stop loss moves in increments of the step size. In the above code, we have defined the step size to be 10. So the trailing stop loss will move in increments of 10 and will always be 50 pips behind the price. Fibonacci levels are used a lot in trading by many traders. You can code an EA that uses Fibonacci levels. The only problem with Fibonacci levels is that they are subjective and each trader will try to draw his own levels. So what to do? Fibonacci Pivot Levels solve this problem by taking the subjective out of the levels. Watch these videos and learn how you can trade with Fibonacci Levels.

CTrailingSL Class

MQL5 unlike MQL4 is an object oriented programming (OOP) language just like C++, Java and Python. Object oriented programming allows us to make classes that we can use again and again. What if we define a CTrailingSL. This class will have all the above features and much more. We don’t need to define the trailing stop loss again. We can define a trailing stop loss object which belongs to this class. Overtime we can also add more functions and methods to this class plus we can also use inheritance and polymorphism and derive new classes from this parent classes that provide us the required functionality that we need. We will define the CTrailingSL class and save the class definition in the include folder in the TrailingSL.mqh file. Below is the code that shows how to do it.

//define the CTrailingSL class
#include <errordescription.mqh>
#include "Trade.mqh"
class CTrailingSL
{
       protected:
            MqlTradeRequest request;

       public:
            MqlTradeResult result;
            bool TrailingStopLoss(string fSymbol, int fTrailPoints, int fMinProfit = 0,
            int fStep = 10);
};



// inform the compiler where to find the class definition
#include <TrailingSL.mqh>
//define the CTrailingSL object trailSL
CTrailingSL trailSL;
// Input variables
input bool useTrailingSL = false;
input int trailingSL = 0;
input int minimumTP = 0;
input int stepSize = 0;

// OnTick() event handler
// Place after order placement code
    if(usseTrailingSL == true && PositionType(_Symbol) != -1)
{
            trailSL.TrailingStopLoss(_Symbol,trailingSL,MinimumTP,stepSize);
}

We start off by defining the CTrailingSL class. MqlTradeRequest is protected while MqlTradeResult is public. We define the boolean funtion TrailingStopLoss that does the grunt work for us.

How To Use A Dynamic Trailing Stop Loss?

The trailing stop loss that we have coded is plain, simple and fixed. As I pointed out price does not move in straight lines. Price whipsaws. Chances are that it will get hit. A easy solution is to make the trailing stop loss dynamic by making it follow an indicator. We can code a trailing stop loss to follow a moving average whether simple or exponential. We can also code a trailing stop loss to follow MACD. We can also use PSAR. We will use the concept of function overloading in our CTrailingSL class to accomplish that. In the above code, we have defined the trailSL object. Below we first use operator overloading to define two different TrailingStopLoss functions. One TradilingStopLoss function has int fTrailPoints and the other has double fTrailPrice.

class CTrailingSL
{
       protected:
          MqlTradeRequest request;
       public:
          MqlTradeResult result;
          bool TrailingStop(string fSymbol, int fTrailPoints, int fMinProfit = 0,
           int fStep = 10);

          bool TrailingStop(string fSymbol, double fTrailPrice, int fMinProfit = 0,
          int fStep = 10);
};

// Input variables
input bool useTrailingSL = false;
input int minimumProfit = 0;
input int stepSize = 0;
input double PSARStepSize = 0.2;
input double PSARMaximum = 0.02;
// OnTick() event handler
double close[];
ArraySetAsSeries(close,true);
CopyClose(_Symbol,0,1,2,close);
// PSAR indicator
double psar[];
ArraySetAsSeries(sar,true);
int psarHandle = iSAR(_Symbol,0,PSARStepSize,PSARMaximum);
CopyBuffer(psarHandle,0,1,2,psar);
// Compare PSAR price with the Close price
bool psarSignal = false;
      if((PositionType(_Symbol) == POSITION_TYPE_BUY && psar[1] < close[1]) || 
         (PositionType(_Symbol) == POSITION_TYPE_SELL && psar[1] > close[1]))
     {
                      psarSignal = true;
     }


// Trailing stop loss
     if(useTrailingSL == true && psarSignal == true)
{
          trailSL.TrailingStopLoss(_Symbol,psar[1],MinimumProfit,stepSize);
}

In the above code we have used PSAR as an example. First we copy the close price to our array close[]. Then we use the CopyBuffer() function to copy psar values to psar[] array. Aftert hat we use an if statement to check if psar value is below the close price or above it and then use it to activate the psarSignal.

How To Code A Breakeven Stop Loss?

Another popular trading strategy that professional traders use is to move the stop loss to breakeven once the profit goes into profit. After that the trade is risk free. If the stop loss gets hit we don’t suffer any loss. Below is how to code a breakeven stop loss. First we define a boolean variable useBreakEven. If it is set to true that we use otherwise we don’t use it.

// Define the Input variables
input bool useBreakEven = false;
input int breakEven = 0;
input int lockProfit = 0;
// OnTick() event handler
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
// Break even stop
if(useBreakEven == true && PositionSelect(_Symbol) == true && breakEven > 0)
{
          request.action = TRADE_ACTION_SLTP;
          request.symbol = _Symbol;
          request.tp = 0;
          long positionType = PositionGetInteger(POSITION_TYPE);
          double currentStop = PositionGetDouble(POSITION_SL);
          double entryPrice = PositionGetDouble(POSITION_PRICE_OPEN);
    if(positionType == POSITION_TYPE_BUY)
     {
          double currentPrice = SymbolInfoDouble(_Symbol,SYMBOL_BID);
          double breakEvenPrice = entryPrice + (lockProfit * _Point);
          double currentProfit = currentPrice - entryPrice;

    if(currentStop < breakEvenPrice && currentProfit >= BreakEven * _Point)
     {
        request.sl = breakEvenPrice;
        OrderSend(request,result);
     }
  }

    else if(positionType == POSITION_TYPE_SELL)
     {
       double currentPrice = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
       double breakEvenPrice = entryPrice - (lockProfit * _Point);
       double currentProfit = entryPrice - currentPrice;
    if(currentStop > breakEvenPrice && currentProfit >= BreakEven * _Point)
      {
               request.sl = breakEvenPrice;
               OrderSend(request,result);
      }
    }
}

We define a breakEvenPrice in the MQL5 code above. We calculate this price and then compare this price with the currentStop. If this is true as well as currentProfit we use OrderSend() function to tell the trade server to change the stop loss.

How To Add BreakEvenSL() function?

We can also add a breakeven() function to our CTrailingSL class. As I had said above, we can add more functions to our class and improve upon our code. We just need to code it once and use the class again and again in our expert advisors.

bool BreakEvenSL(string fSymbol, int fBreakEven, int fLockProfit = 0);

#include <TrailingStops.mqh>
// define the CTrailingSL class
CTrailingSL trailSL;
// Input variables
input bool useBreakEven = false;
input int breakEven = 0;
input int lockProfit = 0;

// OnTick() event handler
if(useBreakEven == true && PositionType(_Symbol) != -1)
{
trailSL.BreakEven(SL_Symbol,BreakEven,LockProfit);
}

This was it. Now you must be clear how you can code a trailing stop loss in your EA. Learning MQL5 can be fun. If you are a serious forex trader and you trade on MT5, you should make some effort to learn MQL5. Now Quants on Wall Street use a lot of Monte Carlo Methods in their trading strategies. Read this post in which I explain how to use Monte Carlo Methods in trading. When it comes to machine learning and artificial intelligence, MQL5 is of no use. We can write a DLL in C/C++ and connect MQL5 with R/Python. R and Python are two very powerful data science languages that have many modules on machine learning and deep learning. More on that in future posts.