Thứ Bảy, 26 tháng 8, 2023

MT5 Trailing Stop Expert

MT5 Trailing Stop Expert

 MT5 Trailing Stop Expert

A trailing stop is nothing more than a stop loss that moves as price changes. For this standard trailing stop the rules are simple:

  • No stop loss is applied if the stop loss is worse than the trade opening price
  • The top loss only moves in a positive direction relative to the trade, staying within a maximum set number of points from the current price.

To enter or modify trades in MT5 I use the CTrade class which is supplied with MT5. Include the Trade.mqh file and declare a global scope variable of the CTrade type

1
2
#include <Trade/Trade.mqh>
CTrade   Trade;

To use the trailing stop you will need to specify the points distance of the trailing stop from the current price. I captured this with an input.

1
input int      InpTrailingStopPoints      =  500;     // Trailing stop points

The input is in points but to use this ofr a trailing stop it must be converted to a price decimal type. I declared a global scope variable to hold the converted value and perform the conversion once in the initialisation section

1
2
3
4
5
double         StopLoss;
int OnInit() {
   StopLoss =  SymbolInfoDouble(Symbol(), SYMBOL_POINT)*InpTrailingStopPoints;
   return(INIT_SUCCEEDED);
}

In the OnTick section place a call to the ApplyTrailingStop function. This call passes all information needed by the function, although all of this information is available through global scope variables it is better practice to pass this information in the function call.

1
ApplyTrailingStop(Symbol(), InpMagicNumber, StopLoss);

Then the ApplyTrailingStop function:

  • Calculate the actual price where buy or sell trailing stops will be placed using the stop loss amount and the appropriate close price.
  • Loop through all open trades
  • Check that the trade matches the symbol and magic number for the expert
  • Depending on buy or sell check that the rules above are met, the new stop loss is better than the opening price and the trade either has no current stop loss or the new stop loss is a better price than the existing stop loss
  • Finally just modify the trade to apply the new stop loss
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void  ApplyTrailingStop(string symbol, int magicNumber, double stopLoss) {
   static int     digits   =  (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   // Trailing from the close prices
   double   buyStopLoss    =  NormalizeDouble(SymbolInfoDouble(symbol, SYMBOL_BID)-stopLoss, digits);
   double   sellStopLoss   =  NormalizeDouble(SymbolInfoDouble(symbol, SYMBOL_ASK)+stopLoss, digits);;
   int      count          =  PositionsTotal();
   for (int i=count-1; i>=0; i--) {
      ulong ticket   =  PositionGetTicket(i);
      if (ticket>0) {
         if (PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_MAGIC)==magicNumber) {
            if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY && buyStopLoss>PositionGetDouble(POSITION_PRICE_OPEN) && (PositionGetDouble(POSITION_SL)==0 || buyStopLoss>PositionGetDouble(POSITION_SL))) {
               Trade.PositionModify(ticket, buyStopLoss, PositionGetDouble(POSITION_TP));
            } else
            if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL && sellStopLoss<PositionGetDouble(POSITION_PRICE_OPEN) && (PositionGetDouble(POSITION_SL)==0 || sellStopLoss<PositionGetDouble(POSITION_SL))) {
               Trade.PositionModify(ticket, sellStopLoss, PositionGetDouble(POSITION_TP));
            }
         }
      }
   }
    
}