MT5 Expert to apply an Automatic Stop Loss

This expert advisor will scan through new trades and automatically apply a default stop loss to trades that have no stop loss

Click here for the MT4 version

Start by using the wizard to create the expert advisor template. I called my expert AutoStopLoss.

For MT5 include the Trade.mqh file to make use of the CTrade class and create an object of type CTrade.

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

This expert uses a simple point value to set the default stop loss. This needs a single input line

input	int	InpStopLossPoints		=	500;	//	Stop loss in points

No code is required in the OnInit or OnDeinit functions, all the work is done in the OnTick function. Begin by declaring a variable to set a time to look back for new trades. Trades placed earlier than the calculated time will not have a stop loss applied

datetime	checkTime	=	TimeCurrent()-30;							//	Only looking at trades in last 30 seconds

Then a standard loop to scan through trades

	int		cnt			=	PositionsTotal();							//	This won't see limit and stop orders
	for (int i=cnt-1; i>=0; i--) {
		ulong ticket	=	PositionGetTicket(i);
		if (ticket>0) {
			if (PositionGetInteger(POSITION_MAGIC)==0 && PositionGetDouble(POSITION_SL)==0) {
								//	magic 0 = manual entry, sl 0 means not set
				if (PositionGetInteger(POSITION_TIME)>checkTime) {					//	lets you override after 30 seconds
					string	symbol			=	PositionGetString(POSITION_SYMBOL);
					double	stopLoss			=	InpStopLossPoints*SymbolInfoDouble(symbol, SYMBOL_POINT);
					double	stopLossPrice	=	(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) ?
														PositionGetDouble(POSITION_PRICE_OPEN)-stopLoss :
					stopLossPrice				=	NormalizeDouble(stopLossPrice, (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS));
					Trade.PositionModify(ticket, stopLossPrice, PositionGetDouble(POSITION_TP));

Line 1 just captures the total number of positions for the loop

Line 2 is the start of the loop counting down from cnt-1 to zero.

Line 3 uses the PositionGetTicket function to both load the position information into memory and return the ticket number. If this fails the ticket number returned will be zero and line 4 then checks that a valid ticket number was returned.

Line 5 checks that the selected order has magic number zero using PositionGetInteger and passing in POSITION_MAGIC which means it was placed manually through the terminal and has no stop loss already applied.

Line 7 then uses the earlier check time to compare open time and avoid any trades placed before the time interval. Without this the expert would repeatedly apply a stop loss if ti is removed. Using the timeout allows you to cancel the stop loss after waiting the selected numebr of seconds and the trade will then be ignored by the expert.

Line 8 loads the symbol for the position into a variable. I use this value more than once and prefer to only call the function one time.

Line 9 calculates the size of the stop loss by converting the points to a price value based on the symbol of the current order

Lines 10-13 then calculate the stop loss price, depending on buy or sell, and ensure that it is a valid normalized price

Finally line 14 applies the updated stop loss price using the CTrade class, by the Trade variable created at the top of the code.

Having Trouble?

If you have the code running and are still having problems here are a few things you can try.

You must have auto trading enabled. That means in Metatrader and for the auto stop loss expert. This expert does not make trades but applying a stop loss to a trade is also auto trading.

This only applies to manual trades. The expert looks for trades you palce manually through the terminal. It does not add a stop loss to trades made by other experts. Trades have a magic number which can be set by experts to any valid integer. Trades entered manually always have a magic number of 0.

Place this expert onto a chart that has a reasonable level of activity. The search for trades to update only happens when there is a tick for the chart where the expert is loaded. If you load it to a chart with very little activity or perhaps lengthy shutdown times then the expert will not find new trades.

This only applies to trades that have no stop loss. If you palce trades with any stop loss at all this expert will not adjust the existing stop loss.

Have the expert running before placing the trade. As well as not updating trades that already have a stop loss the expert will only update trades placed in the last 30 seconds. You can adjust that in the code but 30 seconds is the default. That means if you have existing trades placed more than 30 seconds ago they will not be affected by this expert.

Check the stop loss points. If you set the stop loss too close then normal restrictions in Metatrader will prevent the sl from being applied.

This will not work on netting accounts. It may at times but since there is only a single position for each currency there can only be one stop loss.

This will not work in the strategy tester. It looks for manually entered trades and you can’t do that in the strategy tester. Well, you can by coding new trades in but it’s not worth the trouble.

Trades placed very close to end of day shutdown may be missed. After you palce a trade there is a short delay waiting for the next tick before the trade is found and the stop loss applied. If you placed the trade just before end of day shutdown for your broker then by the time the expert attempts to add the stop loss the market may be closed.

If all above fails, check the experts and journals tabs for any error messages and finally try adding debugging statements to your code to see what is happening. Something like a print statement inside the scanning loop showing the ticket number of each trade found that matched the magic and stop loss tests.



Leave a Reply