Expert advisor trailing stops code

MT4 EA Course: Trailing Stops

This article is part of a series. Here are the other parts:

 

Welcome to the third part of our MetaTrader4 Expert Advisor course! If you haven’t done so, please have a look at first two instalments.

 

Forex Wall-E

In this part, I want to discuss stops. We’ve seen how to create an order with a simple pip-based stop in the previous article. What I want to look at this time, is how to implement dynamic, trailing stops. We’re still working on our Forex Wall-E expert advisor, so let’s continue where we left off!

 

Trailing stops

 

First, let’s talk about what trailing stops are and why you would want to use them. A trailing stop is a stop loss level that will “trail” the current price for a specific distance. Usually, the trailing stop will only move in the direction of your trade. This means that, as the price moves in your direction, the stop loss will move along. Then, if the price suddenly moves against you, the trailing stop will stay at the same level. Because of this, the trailing stop may act as a profit taking level as well.

 

Forex trailing stops

 

Let’s use an example: say you create a buy order EURCAD at 1.30000, with an initial stop loss at 1.20800 (that’s 20 pips) and a trailing stop of 30 pips. If your trade idea was correct and the price moves up to say 1.30500, the trailing stop will have moved along, keeping a 30 pip distance below the current price, so 1.30200. Every time price moves up, our stop loss will trail the current price by a fixed distance of 30 pips. Every time price moves down again, our stop loss will stay at the same level, protecting our profits.

 

 

Advantages of trailing stops

 

The main advantage of having trailing stops is that it protects unrealised profits. If the price has moved your way, having a trailing stop prevents giving away too much of the profits in the event that the price turns around and moves against you.

 

A trailing stop allows you to let profits run and cut losses quickly.

 

Another advantage of trailing stops is ease of trade management. Whereas you previously might need to move your stop loss once in a while, a trailing stop loss provides you with an automatic way to take care of that. There’s no need to micro-manage your trades. Because of the trailing stops, your orders will play themselves out. Knowing you don’t need to check up on the stop loss of your trades also provides extra peace of mind.

 

Finally, it’s a very systematic way to deal with risk management. Your stop will always be x% of your position. Or a fixed number of pips. It provides you with a framework that aligns with your risk and money management profile, so you don’t have to second-guess stop placements.

 

 

Types of trailing stops

 

If you thought there is only one type of pip-based stop, think again! While a trailing stop of a fixed number of pips might be the most common, there is a multitude of ways to trail stops.

 

A lot of them are also described in Van K. Tharp’s excellent book called Trade Your Way To Financial Freedom, which I can really recommend if you’re looking for a good book that helps you in designing your own trading system.

 

Here are some common types of trailing stops:

  • Pip based dynamic (trail x number of pips behind the current price)
  • Pip based fixed (every time price goes x pips in your direction, move stop loss)
  • Volatility trailing stops (e.g. using ATR)
  • Moving Average trailing stops

 

There are other ways to trail stops (e.g. using a percentage based system or using previous support and resistance levels) but I prefer to write a separate article that goes into trailing stops in general. For now, I want to focus on trailing stops within the context of our expert advisor. Therefore, we will start by using a pip based dynamic trailing stop, as this is one of the easiest to implement.

 

 

Trailing Stops in our Expert Advisor

 

Remember our Forex Wall-E Expert Advisor? Let’s continue with that, by looking at the first couple of lines:

 

    if (OrdersTotal() > 0) {
        return;
    }

 

This basically means that if we already have orders open, return and exit the function. We did this to prevent having multiple orders open at the same time. While this is not a requirement at all, it made our Forex Expert Advisor a bit easier to manage.

 

If we want to trail our stops, we will actually have to do something with our open orders. This means that we need to change the above code like this:

 

    if (OrdersTotal() > 0) {
        TrailStops();
        return;
    }

 

What this does, is executing a function called TrailStops if (and only if) we have open orders. We’ve learned about functions before in the second part of our course. Back then, we defined a function called OnTick, which is called every time a tick (or the smallest change in price) happens.

 

However, you might ask: what does this TrailStops function do? That’s what we’re going to define now! This function hasn’t been created yet, and it’s up to us to actually do so. If you were to hit the Compile button right now, you would see that it results in the following error:

 

Compile error

 

 

Defining the TrailStops function

 

We got a “function not defined” error, which makes sense as we haven’t defined it yet. In order to make our expert advisor work, we will add the following block of code below everything else:

 

//+------------------------------------------------------------------+
//| Trailing stop function                                           |
//+------------------------------------------------------------------+
void TrailStops()
{
    int trailingStop = 300;

    for (int i = 0; i < OrdersTotal(); i++) {
        if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
            continue;
        }
 
        if (OrderSymbol() != Symbol()) {
            continue;
        }
 
        if(OrderType() == OP_BUY) {
            if (Bid - OrderOpenPrice() > trailingStop * Point && OrderStopLoss() < Bid - trailingStop * Point) {
                if (!OrderModify(OrderTicket(), OrderOpenPrice(), Bid - trailingStop * Point, OrderTakeProfit(), 0, Green)) {
                    Print("OrderModify error ",GetLastError());
                }
                return;
            }
        }
    }
}

 

Let’s go over this code in some more detail. First, we create the function definition and define a trailing stop distance (30 pips in this case):

 

void TrailStops()
{
    int trailingStop = 300;

 

Then, we create a for-loop, going over every open order we have. For every order we find, we select it using the OrderSelect function. Then, we check if the symbol of the order is actually the symbol we want. There might be orders for other symbols that we don’t want to influence.

 

    for (int i = 0; i < OrdersTotal(); i++) {
        if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
            continue;
        }
 
        if (OrderSymbol() != Symbol()) {
            continue;
        }

 

Note: there are better ways to make sure that we don’t influence orders that haven’t been created by our expert advisor. Because we currently focus on trailing stops, I have omitted these from the code. I will, however, show how to do this in a future part of the course.

 

If everything works out, it means that we have an order for which we potentially can adjust the stop loss in order to trail it. And that’s exactly what happens in the following code block:

 

        if(OrderType() == OP_BUY) {
            if (Bid - OrderOpenPrice() > trailingStop * Point && OrderStopLoss() < Bid - trailingStop * Point) {
                if (!OrderModify(OrderTicket(), OrderOpenPrice(), Bid - trailingStop * Point, OrderTakeProfit(), 0, Green)) {
                    Print("OrderModify error ",GetLastError());
                }
                return;
            }
        }

 

This is the most complex part of our new code, so let’s break it down. First, we check if the order type is actually a buy order. The reason for this is that depending on if it’s a buy or a sell, we will need to change some of our logic (e.g. using the Bid price instead of the Ask price). For now, our expert advisor only creates buy orders, so we only have to check for those.

 

Next, we do some very basic checks inside the if statement. The first one checks that if we subtract the order open price from the current bid price, the result is greater than our predefined trailing stop distance. Implementing this check means that the price first has to move in our favour for at least the distance we have set as our trailing stop (30 pips). Only if this happened, our trailing stop will kick in. This check isn’t necessary, but doing so gives your trade the initial breathing room to make a move.

 

The second check looks at the current stop loss level. Only if that level is smaller than the current Bid price minus our trailing stop distance, we will move our trailing stop. This basically means that we don’t move our stop loss if price retraces back to our open price.

 

Results

 

That’s it! Now, it’s time to hit that Compile button again. If everything went well, you should have no errors. If you do get an error, feel free to have a look at the full code and copy it to your MetaEditor.

 

When we run our updated expert advisor, we get the following results:

 

EA graph with trailing stop

EA results with trailing stop

 

Still not too convincing! But I did notice that our profit factor went up from 1.16 to 1.19 and our absolute and relative drawdown numbers went down. This is a good result and also expected since our trailing stop will make sure that any unrealised gains will not be lost, hence reducing risk.

 

Remember that our goal was to show you how to implement trailing stops, not how to create a profitable expert advisor (at least not yet!). When you try this out, have a play with the various parameters we have defined so far, such as EMA period, trailing stop distance, initial stop loss and take profit levels, and so on. Changing each of these variables will very likely give you a different result in the strategy tester and it’s up to us to find the combination of variables that works the best.

 

 

Conclusion

 

In this article, you’ve learned what trailing stops are, why you might want to use them and which types of trailing stops are available. Then, we modified our expert advisor to implement an example trailing stop and went over the code required to do so.

 

Next time, we will look at making our expert advisor a bit more robust and find out ways we can increase our profitability, while still keeping our drawdown and overall risk profile low. Stay tuned!

 

 

If you have any questions on expert advisors you want to see answered, leave me a note in the comments!

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInShare on TumblrShare on RedditDigg thisShare on StumbleUpon

Felix

I'm a full-time, independent forex trader. I've been trading for over 10 years and specialise in reversal trading, trading psychology, algorithmic trading and coaching others. When I'm not trading, I'll either be travelling the world or rock climbing (likely both). Read my story here.

2 Pingbacks/Trackbacks

  • Pingback: MT4 EA Course: create your own expert advisor()

  • Pingback: MT4 Expert Advisor Forex Course Intro - Smart Forex Learning()

  • Euclid Dsouza

    Hey buddy! Great source of info! honestly the best ive seen so far! Howsoon till the next update?

  • Euclid Dsouza

    Im trying to create an EA that implements 2 EMAS and the RSI, do you think you could help with this in any way?

    • Sure, how about this approach:

      int emaPeriod1 = 50;
      int emaPeriod2 = 100;
      int rsiPeriod = 14;
      double currentEma1 = iMA(NULL, 0, emaPeriod1, 0, MODE_EMA, PRICE_CLOSE, 0);
      double previousEma1 = iMA(NULL, 0, emaPeriod1, 0, MODE_EMA, PRICE_CLOSE, 1);
      double currentEma2 = iMA(NULL, 0, emaPeriod2, 0, MODE_EMA, PRICE_CLOSE, 0);
      double previousEma2 = iMA(NULL, 0, emaPeriod2, 0, MODE_EMA, PRICE_CLOSE, 1);
      double rsi = iRSI(NULL, 0, rsiPeriod, PRICE_CLOSE, 0);

      And to actually trade based on a cross of the ema’s and rsi having some value, you could do something like this:
      if (currentEma1 > currentEma2 && previousEma1 50) {
      // make a trade
      }