How To Code Stop Loss And Take Profit In MQL5?

In this post I am going to discuss in detail how we can code the stop loss, take profit and trailing stop loss in MQL5. In a trade the two most important things are the stop loss and the take profit. Get both of them right and you have a winning trade. Stop loss should be minimal and take profit should be maximal. Sometime it is a better idea to use a trailing stop loss. When it comes to MT5, we have limited trailing stop loss options. In this post we discuss in detail how to code our stop loss, take profit and trailing stop loss when developing an EA in MQL5. Did you read the post on EURNZD sell trade with 5 pip stop loss and 500 pip take profit target? In the screenshot below you can see red dotted lines. These are the stop loss and take profit levels for the GBPUSD buy trade. If price hits stop loss, trade will be automatically closed and if take profit level is hit, trade will be automatically closed as well.

Stop Loss And Take Profit

As said above, in each trade stop loss and profit target are the two most important things. If you have them right, you have a winning trade. if you have them wrong, you will have a losing trade. In algorithmic trading, you should make sure that these two levels are entered correctly so that you don’t suffer a big loss. Algorithmic trading is the future of trading. Even today retail traders are pitted against the algorithmic trader. Algorithmic trader does not need to monitor the charts. Once the EA gets developed and thoroughly tested, it does all the work of monitoring the charts. You need to learn how to code your own EAs and indicators. This is how forex trading is developing. Days of manual trading are over. You cannot watch the charts 24/5. What you can do automated your trading strategy into an EA or an indicator and then use it in your trading. This is the edge that most retail traders are missing. Read the post on USDJPY buy trade with 21 pip stop loss and 700 pip take profit target.

MqlTradeRequest Structure

Let’s start. Before be begin you should become thoroughly familiar with the MqlTradeRequest structure. Structure is a common data format that is used in C and C++. MQL5 has copied a lot of its syntax from C/C++. In simple terms, structure is just a list of different data types that we can combine into one unit. Below is the definition of the MqlTradeRequest structure.

struct MqlTradeRequest
   ENUM_TRADE_REQUEST_ACTIONS    action;           
// Trade operation type
   ulong                         magic;            
// Expert Advisor ID (magic number)
   ulong                         order;            
// Order ticket
   string                        symbol;           
// Trade symbol
   double                        volume;           
// Requested volume for a deal in lots
   double                        price;            
// Price
   double                        stoplimit;        
// StopLimit level of the order
   double                        sl;               
// Stop Loss level of the order
   double                        tp;               
// Take Profit level of the order
   ulong                         deviation;        
// Maximal possible deviation from the requested price
   ENUM_ORDER_TYPE               type;             
// Order type
   ENUM_ORDER_TYPE_FILLING       type_filling;     
// Order execution type
   ENUM_ORDER_TYPE_TIME          type_time;        

// Order expiration type
   datetime                      expiration;       
// Order expiration time (for the orders of ORDER_TIME_SPECIFIED type)
   string                        comment;          
// Order comment
   ulong                         position;         
// Position ticket
   ulong                         position_by;      
// The ticket of an opposite position

Above is the definition of MqlTradeRequest structure. As you can see it can hold a lot of information about a position. This information is in the shape of enums, datatime, ulong, string and double data type. If you look closely, you will find the stop loss sl and take profit tp in this data structure. If you want to design and develop expert advisors, you should become thoroughly familiar with MqlTradeRequest structure. So let’s discuss this data structure in detail. MqlTradeRequest contains the following information: action which tells the server what type of action is required, currency symbol, volume which will be the number of lots of the position, price, stop loss, take profit, deviation, type is the type of order that can be market order as well as pending orders and type of fillings. We need to discuss each thing in detail. Learn how to use support vector machine in trading.

At the top we have ENUM_TRADE_REQUEST_ACTIONS. Enums are just like structures. The only difference is that enums are always of the same data type integer. TRADE_ACTION_DEAL is used to place a market order immediately with specified volume, take profit and stop loss. TRADE_ACTION_PENDING is used to specify a pending order that can be Buy limit order, buy stop order, sell limit order and sell stop order. TRADE_ACTION_SLTP is for modifying the exiting open position take profit and stop loss values.TRADE_ACTION_MODIFY is for modifying a previously placed pending order. TRADE_ACTION_REMOVE is for deleting an existing pending order. TRADE_ACTION_CLOSE_BY closing an open position by placing an exact opposite position. Download your free copy of the Traders World Magazine.

Magic number is very important for each expert advisor. Trading server tracks each expert advisor by assigning it a magic number. This is a ulong number which means a positive number. Keep this in mind magic number is unique to each expert advisor. Next comes the Order ID. This Order ID is used to track each order that has been placed by an expert advisor. Trade symbol is a string variable that is specified after the Order ID. Trading symbol can be EURUSD, GBPUSD, USDJPY etc. Volume is the number of lots that is used to open the position. This is a double variable. Price is the order opening price.

Stoplimit is for pending limit orders. Action variable should be set to TRADE_ACTION_PENDING. Type variable should be set to ORDER_TYPE_BUY_STOP_LIMIT or ORDER_TYPE_SELL_STOP_LIMIT. Stop loss sl should be when placing a market order or a pending order. Take profit tp should also be specified when placing a market order or a pending order. You can change sl and tp later on. Deviation is used for both market orders as well pending orders. Specifying deviation limits slippage when placing market orders For example if you click buy EURUSD with price 1.12413, slippage may cause the order to be executed at 1.12524 when the market is fast moving. You can set deviation to 3 points which means EURUSD buy order will not be executed if price exceeds about 1.12443 + spread. Order type is an enum with the following types: ORDER_TYPE_BUY, ORDER_TYPE_SELL, ORDER_TYPE_BUY_STOP, ORDER_TYPE_SELL_STOP, ORDER_TYPE_BUY_LIMIT, ORDER_TYPE_BUY_STOP_LIMIT and ORDER_TYPE_SELL_SELL_LIMIT. Learn how to use artificial intelligence in your forex trading system.

Order execution type is an enum type_filling with values ORDER_FILLING_FOK, ORDER_FILLING_IOC and ORDER_FILLING_RETURN. ORDER_FILLING_FOK means fill or kill. This means if the order cannot be filled at the specified price and volume it will be deleted. ORDER_FILLING_IOC means immediate or cancel meaning if the order with the specified price and volume cannot be filled than only a partial order will be filled later. ORDER_FILLING_RETURN means if the order is not filled at the specified price and volume it will filled later on with unfilled volume.

Order expiration time is again an enum with values ORDER_TIME_GTC, ORDER_TIME_DAY and ORDER_TIME_SPECIFIED. ORDER_TYPE_GTC means good till cancelled. The pending order will not expired until deleted by the trader. When we use ORDER_TIME_SPECIFIED, we have to also specify  the time in datetime when the order will expire. Order comment is a string that provides you the opportunity to make a comment for your own perusal when placing the order. This is important. We can initialize an MqlTradeRequest structure easily with request.

Predefined Variables in MQL5

MQL5 has some predefined variables that are frequently used as paramters. _Symbol is the current chart currency pair symbol. _Period is the predefined variable for the current chart in minutes. _Point is the pip value for the current symbol. For a five digit currency pair it is 0.00001 and for three digit Yen currency pairs like USDJPY, EURJPY, GBPJPY etc, it is 0.001. _Digits is the number of digits for the currency pair which can be 5 digits for most pairs and 3 digits for Yen pairs as said above..

MqlTradeResult Structure

Before we proceed, you should also become familiar with MqlTradeResult structure. Both MqlTradeRequest and MqlTradeResult structures are important when coding an EA. Below is the definition of the MqlTradeResult structure.

struct MqlTradeResult
   uint     retcode;          
// Operation return code
   ulong    deal;             
// Deal ticket, if it is performed
   ulong    order;            
// Order ticket, if it is placed
   double   volume;           
// Deal volume, confirmed by broker
   double   price;            
// Deal price, confirmed by broker
   double   bid;              
// Current Bid price
   double   ask;              
// Current Ask price
   string   comment;          
// Broker comment to operation 
// By default it is filled by description of trade server return code
   uint     request_id;       
// Request ID set by the terminal during the dispatch 
   uint     retcode_external; 
// Return code of an external trading system

You can see in the above definition, MqlTradeResult structure is used to store values for an open trade. First is the uint retconde which is important.  When you place the request for trade order using MqlTradeRequest using OrderSend(), the trade server places the trade order execution results in structure MqlTradeResult. 10004 retcode TRADE_RETCODE_REQUOTE means requote. 10006 retcode TRADE_RETCODE_REJECT means the trade request has been rejected. 10008 retcode TRADE_RETCODE_PLACED means order has been successfully placed. 10018 retcode TRADE_RETCODE_MARKET_CLOSED means market is closed. You will get this retcode when you try to open a buy/sell order on the weekend. 10026 retcode TRADE_RETCODE_SERVER_DISABLES_AT means autotrading has been disabled on your MT5 terminal. You should first enable it before you start autotrading. 10044 is the last retcode enum value. Learn these 8 machine learning algorithms that you can use in your EA.

Deal ticket is a ENUM_TRADE_REQUEST_ACTIONS. TRADE_ACTION_DEAL means to place a trade order for immediate execution. Trade Order Type is also used in MqlTradeRequest. So you should be familiar with it by now. Order ticket is applicable if the order has been placed. Price, bid and ask also can be accessed through this MqlTradeResult structure. You should make yourself familiar with these two important structures MqlTradeRequest and MqlTradeResult.

How To Place Stop Loss And Take Profit For An Already Opened Order?

Stop loss is always calculated from the entry price. For example, suppose you have opened a EURUSD buy order with entry price of 1.12412, We want the order to be closed if EURUSD price goes below 1.12212. This is the stop loss which is 20 points (pips). We will use this _Point double variable that calculates the point size of the quote currency.

// define stop loss size and take profit size
input int StopLoss = 200;
input int TakeProfit = 1000;
// 200 means 20 pips
// 1000 means 100 pips
// OnTick() event handler
//define the MqlTradeRequest structure variable
MqlTradeRequest request;
//define the MqlTradeResult variable
MqlTradeResult result;
// reset the MqlTradeRequest structure
request.action = TRADE_ACTION_SLTP;
request.symbol = _Symbol;
// Calculate the stop loss for a buy position
// get the entry price of the buy order
double positionPrice = PositionGetDouble(POSITION_PRICE_OPEN); //A
//calculate the size of the stoploss in points
double stopLossPoint = StopLoss * _Point; //B
// fix the sl = positionPrice – stopLossPoint; //C
// calculate the size of take profit in points
double takeProfitPoint = TakeProfit * _Point; //D
//fix the tp = positionPrice + takeProfitPoint;
//tell the trade server to fix sl and tp
OrderSend(request,result); //E

Above is the example code for modifying the stop loss of an already open order. We will place the above code in OnTIck() event handler. First we fine the stop loss variable StopLoss and give it a value of 200. Then we define a MqlTradeRequest structure request and MqlTradeResult structure result. ZeroMemory(0 function is used to reset the MqlTradeRequest structure request. We fix MqlTradeRequest Action with request.action and give it a value TRADE_ACTION_SLTP. Then we fix the symbol as _Symbol. You can see we calculated the stopLossPoint as StopLOss*_Point. _Point is 0.00001 for a 5 digit broker. Since we have StopLoss as 200, stopLossPoint comes out to 20 pips. In C and D we fix the sl and tp value in structure MqlTradeRequest and then send the order using OrderSend() in E. In A we have used PositionGetDouble(POSITION_PRICE_OPEN) to get the positionPrice which then we use in C to fix the stop loss value in MqlTradeRequest. In case of a sell order we will just add the stopLossPoint instead of subtracting it.Similarly we will subtract the takeProfitPoint from positionPrice. Watch this webinar on the only candlestick pattern you will ever need.

How To Place Stop Loss And Take Profit For A Pending Order?

In case of a pending order we can place the stop loss order at the time of placing the pending order by using the entry price. Below is a sample code for placing a stop loss order for a buy stop pending order.

// define the stop loss value
input int StopLoss = 300;
input int TakeProfit = 1500; 
// 300 means 30 pips
// 1500 means 150 pips
input int PendingPrice = 100;
// OnTick() event handler
MqlTradeRequest request;
MqlTradeResult result;
request.action = TRADE_ACTION_PENDING;
request.type = ORDER_TYPE_BUY_STOP;
request.symbol = _Symbol;
request.volume = 0.5;
request.type_time = ORDER_TIME_GTC;
// Calculate SL and TP for a pending buy order
request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK) + (PendingPrice * _Point);
double stopLossPoint = StopLoss * _Point;
double takeProfitPoint = TakeProfit * _Point; = request.price - stopLossPoint; = request.price + takeProfitPoint;

Above is the code for placing SL and TP for a pending order. You can see it is many lines of code. Can we build a class that can help us reduce the above code. Defining a class will need writing code once. After that we can use that class again and again. If you are a serious ea programmer than you should develop such a class that will have the methods that will easily change SL and TP without much work. Just include that class in that include file. I am not going to develop such a class but you will ultimately have to develop it if you want to code expert advisors.

What Is Stop Level?

Stop level is very important for you to know. Stop level is the minimum distance from the current bid/ask price the entry price, stop loss and take profit should be. If you will try to place a pending order within the stop level, it will be rejected by the trade server with the retcode TRADE_RETCODE_INVALID_STOPS (10016).  We use the function SymbolInfoInteger() to retrieve the stop level.

double stoplossLevel = SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL) * _Point;
double minimumStopLevel = SymbolInfoDouble(_Symbol,SYMBOL_ASK) + stoplossLevel;

First we call SymbolInfoInteger(0 function and then multiply it with the _Point predefined variable that has a value 0.00001 for 5 digit brokers for most pairs and is 0.001 for JPY pairs. By multiplying it with _Point we convert SymbolInfoInteger() value into price. We then add this price to the ask price we retrieve using SymbolInfoDouble() function. Now any buy take profit, sell stop loss, buy stop and sell limit price should be above this minStopLevel otherwise when we use OrderSend() function we will get TRADE_RETCODE_INVALID_STOPS retcode. Similarly for sell take profit, buy stop loss, sell stop and buy limit we will have to add stoplevel to SymbolInfoDouble() function like below:

double stoplossLevel = SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL) * _Point;
double minimumStopLevel = SymbolInfoDouble(_Symbol,SYMBOL_BID) - stoplossLevel;

Before you place the stop loss, you should compare it with the stop level and check whether your stop loss is valid or not. You can use the following code.

double stoplossLevel = SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL) * _Point;
double minimumStopLevel = SymbolInfoDouble(_Symbol,SYMBOL_ASK) + stoplossLevel;
if(request.price <= minimumStopLevel)
Print("Invalid stop loss price");

If you get this message Invalid stop price, it means your stop loss is within the stop level.

How To Create Stop Verification Functions?

As said above before we place a market order or a pending order we need to check price is not within the stop level. Always make sure that your trade has got the stop loss and take profit target properly entered. You should become thoroughly familiar with CTrade class which is part of the MQL5 Standard Library.You can use the CTrade class allows you to place buy/sell trades as well as get the required infromation. For example, you can use RequestSL() method to get the stop loss that has been entered in the order. Similarly you can use RequestTP() method to get the take profit that has been entered in the order. I have shown you in this post how to calculate the stop loss and take profit levels. CTrade class is a comprehensive lass that you can use to open, close and modify buy/sell orders.

Now MQL5 is a better language as compared to MQL4. MQL4 was a structural programming language which lacked object oriendted capabilities. MQL5 is a full fledged object programing language which has been modeled on C++.In the future post I will show you how to write a DLL in C++ that will connect MT5 with R. R is a powerful data science and machine learning language that can make your EAs much more powerful. For example suppose you want to use a Kalman Filter in your trading. You will have to wrtie a Kalman Filter class in MQL5 which can be a laborious and time consuming job. Using R you have many packages that provide full fledged Kalman Filter. For example DLM package gives you the chance to build Kalman Filters that includes Extended Kalman Filter as well as Unscented Kalman Filter as well as partilce filter. If you are interested in learning R, you can take a look at my courses on R. First course is R for Traders. This course is for beginners who are knew to data science and R language. Once you master R, you can take a look at my course R Machine Learning for Trader. Finally you can take my course R for Algorithmic Trading. MQL5 has now fuzzy logic library. But it has many limitations. It cannot deal with type 2 fuzzy system. Once again if you wan to enhance the power of MQL5, you should connect it with R by writing a DLL. More on that in future posts.

About The Author


I have done masters from Harvard University. I am interested in day trading currencies, options and stocks.