MT5 Trailing Stop Expert

This is a function that you can use in your MT5 expert advisor to apply a standard points based trailing stop

For the MT4 verison click here

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

#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.

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

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.

	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
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));
				}
			}
		}
	}
	
}

15 Comments

  1. Getting the following errors

    line (27) CreateTrades(Symbol(), inpVolume, InpMagicNumber, InpTradeComment);
    Errors
    1 – ‘CreateTrades’ undeclared identifier error
    4x – Unexpected token errors
    1- ‘symbol’ – some operator expected error
    2x – Expression has no effect error

    line(29)
    ApplyTrailingStop(Symbol(), InpMagicNumber, StopLoss);
    1 – ‘ApplyTrailingStop’ undeclared identifier error
    3x – Unexpected token errors
    1 – Expression has no effect error
    1- ‘symbol’ – some operator expected error

    line(33)
    ‘ { ‘ unbalanced parentheses

    line(80)
    ‘ } ‘ unexpected end of program

  2. #include
    CTrade Trade;

    input int InpTrailingStopPoints = 500; // Trailing stop points

    double StopLoss;
    int OnInit() {
    StopLoss = SymbolInfoDouble(Symbol(), SYMBOL_POINT)*InpTrailingStopPoints;
    return(INIT_SUCCEEDED);
    }

    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));
    }
    }
    }
    }

    }

      1. I will like to request a Expert Adviser which uses stochastic on MT5… i have the code for it in MT4 but i cant migrate it in MT5,
        So i was just requesting if i can send you the code maybe on Email so that you can migrate it for me to mt5

  3. //+——————————————————————+
    //| Trailingstop.mq5 |
    //| Copyright 2022, MetaQuotes Ltd. |
    //| https://www.mql5.com |
    //+——————————————————————+
    #property copyright “Copyright 2022, MetaQuotes Ltd.”
    #property link “https://www.mql5.com”
    #property version “1.00”
    //+——————————————————————+
    //| Expert initialization function |
    //+——————————————————————+
    #include
    CTrade Trade;

    input int InpTrailingStopPoints = 500; // Trailing stop points

    input int inpMagicNumber = 212121;
    input string inpTradeComment = “justtesting”;
    input double inpVolume = 0.01;

    double StopLoss;

    double StopLoss;
    int OnInit() {
    StopLoss = SymbolInfoDouble(Symbol(), SYMBOL_POINT)*InpTrailingStopPoints;
    return(INIT_SUCCEEDED);
    }

    void OnDeinit(const int reason) {
    }

    void onTick() {

    CreateTrades(Symbols(), inpVolume, inpMagicNumber, inpTradeComment);

    ApplyTrailingStop(symbol(), inpMagicNumber, StopLoss);

    }
    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 = PositionTotal();
    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 || sellStopLoss0;i–) {
    ulong ticket = PositionGetTicket(i);
    if (PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_MAGIC==magicNumber) {
    if(PositionGetInteger(POSITION_TYPE)==ORDER_TYPE_BUY) buyCount++;
    if(PositionGetInteger(POSITION_TYPE)==ORDER_TYPE_SELL) sellCount++;
    }
    }
    }

    if (buyCOUNT==0) {
    if (Trade.PositionOpen(symbols, ORDER_TYPE_BUY, volume, SymbolInfoDouble(symbol,SYMBOL_ASK),0.0,tradeComment)) {}

    if (sellCOUNT==0) {
    if (Trade.PositionOpen(symbols, ORDER_TYPE_SELL, volume, SymbolInfoDouble(symbol,SYMBOL_BID),0.0,tradeComment)) {}

    1. hi

      i dont know what im doing wrong.

      ‘StopLoss’ – variable already defined TrailingStop.mq5 14 16

      ‘}’ – expressions are not allowed on a global scope TrailingStop.mq5 56 1

      ‘else’ – expressions are not allowed on a global scope TrailingStop.mq5 56 3

      ‘}’ – unexpected end of program TrailingStop.mq5 76 1

      ambiguous access, can be one of: TrailingStop.mq5 16 4

      ‘StopLoss’ – l-value required TrailingStop.mq5 16 4

      ‘CreateTrades’ – undeclared identifier TrailingStop.mq5 27 1

      ‘,’ – unexpected token TrailingStop.mq5 27 22

      ‘Symbol’ – some operator expected TrailingStop.mq5 27 14

      ‘inpTradeComment’ – undeclared identifier TrailingStop.mq5 27 51

      ‘InpMagicNumber’ – undeclared identifier TrailingStop.mq5 29 29

      ‘Trade’ – undeclared identifier TrailingStop.mq5 46 16

  4. Thanks – it does include
    #include
    CTrade Trade;

    The errors are below –
    ‘}’ – unexpected end of program Trailingstop.mq5 115 14
    ‘{‘ – unbalanced parentheses Trailingstop.mq5 47 15
    2 errors, 0 warnings 3 1

    1. Then that is the answer. You have a missing } or an extra { somewhere. Maybe the other way around. The editor can highlight matching {} to help tracking down the problem.

  5. It is giving me compile error –

    #include
    CTrade Trade;

    input int InpTrailingStopPoints = 500; // Trailing stop points

    input int InpMagicNumber = 212121;
    input string InpTradeComment = “just testing”;
    input double InpVolume = 0.01;

    double StopLoss;
    int OnInit()
    {

    StopLoss = SymbolInfoDouble(Symbol(), SYMBOL_POINT)*InpTrailingStopPoints;

    Trade.SetExpertMagicNumber(InpMagicNumber);

    //—

    //—
    return(INIT_SUCCEEDED);
    }
    //+——————————————————————+
    //| Expert deinitialization function |
    //+——————————————————————+
    void OnDeinit(const int reason)
    {
    //—

    }
    //+——————————————————————+
    //| Expert tick function |
    //+——————————————————————+
    void OnTick() {

    createTrades(Symbol(),InpVolume,InpMagicNumber,InpTradeComment);

    ApplyTrailingStop(Symbol(),InpMagicNumber,StopLoss);

    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–1) {
    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=0; i–) {
    ulong ticket = PositionGetTicket(i);
    if (ticket>0) {
    if (PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_MAGIC)==magicNumber) {
    if (PositionGetInteger(POSITION_TYPE)==ORDER_TYPE_BUY) buyCount++;
    if (positionGetInteger(POSITION_TYPE)==ORDER_TYPE_SELL) sellCount++;
    }

    }

    }

    if (buycount==0) {
    if (Trade.positionOpen(symbol, ORDER_TYPE_BUY, volume, SymbolInfoDouble(symbol, SYMBOL_ASK),0,0,tradecomment)){}
    }
    if (sellcount==0) {
    if (Trade.PositionOpen(symbol,ORDER_TYPE_SELL, volume, SymbolInfoDouble(symbol, SYMBOL_BID),0,0,tradecomment)){}
    }

    }

Leave a Reply