Trailing Stop in MetaTrader 4

Trailing stop allows you to automatically protect the profits with your positions. It adjusts itself according to the current market rate and the amount of pips you give it to trail behind. Trailing stop is a great tool for the conservative and long term traders as it easily creates protective «airbag» for the trades. There are two basic ways to set the trailing stop in your MetaTrader 4 platform — use the built-in tool and attach a special EA that will apply a single trailing stop to all orders. But before going into describing these ways I’d like to tell you how the correct trailing stop should work:

  • It should go into the action only when the position is in profit (or at a break even point).
  • It should apply itself only when the difference between the current stop-loss and the current market price is greater than the trailing stop value.
  • Trailing stop should never «decrease» the stop-loss level.
  • If used without the initial stop-loss, trailing stop doesn’t protect your position from the excess losses; it only provides a good profit-following tool.
  • Here are the details on these two ways:
    The most easy and convenient way to set the trailing stop-loss is to click with the right mouse button on the order in the Terminal window and select the Trailing Stop submenu. There you’ll be able to either choose some of the preset amount of pips or enter a custom number:


    This way of setting your trailing stop-loss is very convenient but it has two important disadvantages. The first con is that it doesn’t allow trailing stop lower than 15 pips. That’s probably not a problem for long-term traders, but it’s a great trouble for scalpers and short-term traders. And the second disadvantage of this method is that it doesn’t work properly with the brokers that provide extended quotes (5 and 3 digits after the dot instead of 4 and 2 digits). Trailing stop confuses the pips in this case and acts incorrectly.
    The second method is to add a special expert advisor to some chart in your MetaTrader 4 platform and it will follow all open orders trying to apply the trailing stop value you give it in the input parameter. This is a very simple expert advisor that doesn’t load up your system resources and can be turned on and off anytime. Here is its code:

    #property copyright "Copyright © 2009-2015, EarnForex.com"
    #property link      "http://www.earnforex.com"
     
    /*
       Kicks in when position reaches at least TrailingStop pips of profit.
    */
     
    extern double TrailingStop = 5;
     
    // Set it to some value above 0 to activate stop-loss
    extern double StopLoss = 0; 
     
    int init()
    {
       return(0);
    }
     
    int deinit()
    {
       return(0);
    }
     
    int start()
    {
      double PointValue;
      for (int i = 0; i < OrdersTotal(); i++) 
      {
          OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
          if (OrderSymbol() != Symbol()) continue; // Skipping positions in other currency pairs
          //Calculate the point value in case there are extra digits in the quotes
          if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.00001) PointValue = 0.0001;
          else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.001) PointValue = 0.01;
          else PointValue = MarketInfo(OrderSymbol(), MODE_POINT);
          //Normalize trailing stop value to the point value
          double TSTP = TrailingStop * PointValue;
     
          if (OrderType() == OP_BUY)
          {
             if (Bid - OrderOpenPrice() > TSTP)
             {
                if (OrderStopLoss() < Bid - TSTP)
                {
                   if (!OrderModify(OrderTicket(), OrderOpenPrice(), Bid - TSTP, OrderTakeProfit(), OrderExpiration(), clrNONE))
                      Print("Error setting Buy trailing stop: ", GetLastError());
                }
             }
             else if ((OrderStopLoss() != Bid - StopLoss * PointValue) && (StopLoss != 0) && (OrderStopLoss() == 0))
                if (!OrderModify(OrderTicket(), OrderOpenPrice(), Bid - StopLoss * PointValue, OrderTakeProfit(), OrderExpiration(), clrNONE))
                   Print("Error setting Buy stop-loss: ", GetLastError());
          }
          else if (OrderType() == OP_SELL)
          {
             if (OrderOpenPrice() - Ask > TSTP)
             {
                if ((OrderStopLoss() > Ask + TSTP) || (OrderStopLoss() == 0))
                {
                   if (!OrderModify(OrderTicket(), OrderOpenPrice(), Ask + TSTP, OrderTakeProfit(), OrderExpiration(), clrNONE))
                      Print("Error setting Sell trailing stop: ", GetLastError());
                }
             }
             else if ((OrderStopLoss() != Ask + StopLoss * PointValue) && (StopLoss != 0) && (OrderStopLoss() == 0))
                if (!OrderModify(OrderTicket(), OrderOpenPrice(), Ask + StopLoss * PointValue, OrderTakeProfit(), OrderExpiration(), clrNONE))
                   Print("Error setting Sell stop-loss: ", GetLastError());
          }
    	}
     
       return(0);
    }

    /*
    Kicks in when position reaches at least TrailingStop pips of profit.
    */

    extern double TrailingStop = 5;

    // Set it to some value above 0 to activate stop-loss
    extern double StopLoss = 0;

    int init()
    {
    return(0);
    }

    int deinit()
    {
    return(0);
    }

    int start()
    {
    double PointValue;
    for (int i = 0; i < OrdersTotal(); i++) { OrderSelect(i, SELECT_BY_POS, MODE_TRADES); if (OrderSymbol() != Symbol()) continue; // Skipping positions in other currency pairs //Calculate the point value in case there are extra digits in the quotes if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.00001) PointValue = 0.0001; else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.001) PointValue = 0.01; else PointValue = MarketInfo(OrderSymbol(), MODE_POINT); //Normalize trailing stop value to the point value double TSTP = TrailingStop * PointValue; if (OrderType() == OP_BUY) { if (Bid - OrderOpenPrice() > TSTP)
    {
    if (OrderStopLoss() < Bid - TSTP) { if (!OrderModify(OrderTicket(), OrderOpenPrice(), Bid - TSTP, OrderTakeProfit(), OrderExpiration(), clrNONE)) Print("Error setting Buy trailing stop: ", GetLastError()); } } else if ((OrderStopLoss() != Bid - StopLoss * PointValue) && (StopLoss != 0) && (OrderStopLoss() == 0)) if (!OrderModify(OrderTicket(), OrderOpenPrice(), Bid - StopLoss * PointValue, OrderTakeProfit(), OrderExpiration(), clrNONE)) Print("Error setting Buy stop-loss: ", GetLastError()); } else if (OrderType() == OP_SELL) { if (OrderOpenPrice() - Ask > TSTP)
    {
    if ((OrderStopLoss() > Ask + TSTP) || (OrderStopLoss() == 0))
    {
    if (!OrderModify(OrderTicket(), OrderOpenPrice(), Ask + TSTP, OrderTakeProfit(), OrderExpiration(), clrNONE))
    Print(“Error setting Sell trailing stop: “, GetLastError());
    }
    }
    else if ((OrderStopLoss() != Ask + StopLoss * PointValue) && (StopLoss != 0) && (OrderStopLoss() == 0))
    if (!OrderModify(OrderTicket(), OrderOpenPrice(), Ask + StopLoss * PointValue, OrderTakeProfit(), OrderExpiration(), clrNONE))
    Print(“Error setting Sell stop-loss: “, GetLastError());
    }
    }

    return(0);
    }

    As you see, the code is really simple. You can also download this trailing stop EA and use it freely with your orders. This version will start trailing stop-loss when position reaches profit, which is greater or equal to your given trailing stop value. You can also download a trailing stop EA that will start working when any positive profit has been reached or the one that will trail stop-loss immediately whenever current stop-loss lags behind the current price for the given trailing stop value. The latter version does not have a common stop-loss function for obvious reasons.
    While it lacks the disadvantages of the first MetaTrader trailing stop method, unfortunately, it also has two of its own important disadvantages. First, it works for all currently open orders. So, if you want attach it to only one order and leave another one without a trailing stop this method is not for you (but, of course, you can alter this EA to work with some specific orders). Second, it utilizes the same trailing stop value for all orders, you can’t set 10 pips trailing stop for one position and 50 trailing stop for another one. In case you want to use different stop-loss values for different orders you’ll have to heavily alter the code of this MT4 expert advisor.
    Update: Added stop-loss option, which might be useful if you want to complement some expert advisor that doesn’t set stop-losses on its positions.
    Update 2013-02-28: Added two other versions of MT4 trailing stop. Please see the paragraph below the source code for more details. The original version has been also updated for some error reporting capability.
    Update 2013-07-31: Fixed stop-loss modification error, which could potentially move the SL level backwards. Thanks to Reynald for reporting this bug.
    Update 2014-04-27: Added a check for the position’s currency pair. The trailing stop EA will now only work for the positions of the currency pair it is attached to. Previously, it would work erroneously by trying to apply Bid/Ask of the symbol it is attached to to other trading symbols. (Thanks to mikeyh for reporting this.)
    Update 2015-10-30: Fixed OrderModify() function call to avoid modification of order expiration parameter. Also, removed arrow color for order modification to reduce the chart noise.

    If you have some questions, suggestions or bug reports regarding the presented trailing stop code, please feel free to share them using the form below.

    Leave a Reply

    Your email address will not be published. Required fields are marked *