Trailing stop with the Max Favorable Excursion (MFE)

I already posted an article about a complete trailing stop function in the blog a short time ago. This time I’ll make it with a different logic with the help of the MFE , the Max Favorable Excursion.

What is the MFE?

The MFE is the maximum of gain a trade has met since its inception price. I can also describe it as: the highest price a long trade has encountered or the lowest one for a short trade.

What we plan here is to use the MFE to exit our trades on price retracement:

trailing stop function MFE

Max Favorable Excursion calculation

To save the actual price only if it is lower (for a short trade) or higher (for a long trade), we use the MIN and MAX mathematical function of Probuilder:

//case SHORT order
if shortonmarket then
 MINPRICE = MIN(MINPRICE,close) //saving the MFE of the current trade
endif

//case LONG order
if longonmarket then
 MAXPRICE = MAX(MAXPRICE,close) //saving the MFE of the current trade
endif

That’s it, MFE are saved for future purpose in our trailing stop function.

When not on market, we have to reset the whole variables to not interfere with the new trades that will use them for trailing purpose:

//resetting variables when no trades are on market
if not onmarket then
 MAXPRICE = 0
 MINPRICE = close
endif

MINPRICE is set to current close, because no price can be lower than 0.

 

A trailing stop based on MFE

Let’s assume we want the trailing stop function to become active only if the MFE has reached 20 points from the entry price of your current trade.

First declare the parameter variable:

//trailing stop
trailingstop = 20

This variable will also be used to determine price retracement from the MFE to close the order.

Next step is to define the price level where to exit the current trade accordingly to the MFE and our trailing stop variable:

//case SHORT order
if shortonmarket then
 MINPRICE = MIN(MINPRICE,close) //saving the MFE of the current trade
 if tradeprice(1)-MINPRICE>=trailingstop*pointsize then //if the MFE is higher than the trailingstop then  
  priceexit = MINPRICE+trailingstop*pointsize //set the exit price at the MFE + trailing stop price level
 endif
endif

//case LONG order
if longonmarket then
 MAXPRICE = MAX(MAXPRICE,close) //saving the MFE of the current trade
 if MAXPRICE-tradeprice(1)>=trailingstop*pointsize then //if the MFE is higher than the trailingstop then
  priceexit = MAXPRICE-trailingstop*pointsize //set the exit price at the MFE - trailing stop price level
 endif
endif

The trades will always exit if the price retrace more or equal to 20 points from the current MFE. The “exitprice” levels are moving accordingly to the MFE at each new candlestick.

Now that the “exitprice” variable is set (the price level where to exit trades), we have to deal with the orders exit, so we build STOP orders among the exit price levels:

//exit on trailing stop price levels
if onmarket and priceexit>0 then
 EXITSHORT AT priceexit STOP
 SELL AT priceexit STOP
endif

The complete code of the MFE trailing stop function

If you have to copy/paste something in your own prorealtime code, this is the whole function for doing it:

//trailing stop
trailingstop = 20

//resetting variables when no trades are on market
if not onmarket then
 MAXPRICE = 0
 MINPRICE = close
 priceexit = 0
endif

//case SHORT order
if shortonmarket then
 MINPRICE = MIN(MINPRICE,close) //saving the MFE of the current trade
 if tradeprice(1)-MINPRICE>=trailingstop*pointsize then //if the MFE is higher than the trailingstop then  
  priceexit = MINPRICE+trailingstop*pointsize //set the exit price at the MFE + trailing stop price level
 endif
endif

//case LONG order
if longonmarket then
 MAXPRICE = MAX(MAXPRICE,close) //saving the MFE of the current trade
 if MAXPRICE-tradeprice(1)>=trailingstop*pointsize then //if the MFE is higher than the trailingstop then
  priceexit = MAXPRICE-trailingstop*pointsize //set the exit price at the MFE - trailing stop price level
 endif
endif

//exit on trailing stop price levels
if onmarket and priceexit>0 then
 EXITSHORT AT priceexit STOP
 SELL AT priceexit STOP
endif

I also attached to this blog article a “basic” EMA cross automated trading system built with this functionality.

 

Share this

  1. Adolfo • 320 days ago #

    Thanks a lot for this Nicolas! 🙂

  2. Andres • 318 days ago #

    Thanks, Nicolas!!!

  3. manel • 318 days ago #

    Thanks Nicolas, this indeed looks very useful.

    Could the trailing stop be coded as a % of the price instead of fixed amount of points in order to take into account different absolute price levels across instruments ? eg. retraces 0.5% from the MFE

  4. manel • 318 days ago #

    Sorry, I realise that may be a basic question so I’ve tried to code it myself, would this work ? eg:

    trailingstop = 0.5%
    
    //case SHORT order
    if shortonmarket then
     MINPRICE = MIN(MINPRICE,close) //saving the MFE of the current trade
     if tradeprice(1)-MINPRICE>=trailingstop*tradeprice*pointsize then //if the MFE is higher than the trailingstop then  
      priceexit = MINPRICE+trailingstop*tradeprice*pointsize //set the exit price at the MFE + trailing stop price level
     endif
    endif

     

    • Nicolas • 318 days ago #

      Your code is not adapted, but your idea is good. I’ll try to write another article about it in a few days. Thanks! 😉

  5. manel • 318 days ago #

    Thanks for that, look forward to it. I realised that the code does not accept 0.5% so I used 0.005 instead and it seemed to work and some of the backtesting produces nice results but the calculation does not equal 0.5% when exiting so something is obviously not quite correct.

  6. Stef • 300 days ago #

    Hi @Nicolas. I think this should read “Max Favorable Excursion.”

    • Nicolas • 300 days ago #

      OMG that’s right 🙂 thanks!

  7. Stef • 206 days ago #

    @Nicolas,

    Another idea would be to calculate the Maximum Adverse Excursion (MAE) (points/percent) for each trade, to try to determine at which point trades do not seem to recover from. This can then be used to set a catastrophic stop loss. If a trade moves beyond this point, then chances are it will not recover, and it is better to walk away.

    Stef

    • Nicolas • 206 days ago #

      You are right, this is something often calculated while developing automated trading strategy to determine the right stoploss level for each trade. Maybe I’ll do it later, or if someone has the coding abilities to, just do it! 🙂

  8. baaz • 203 days ago #

    When I copy the code and use instead of the built in “pTRAILING” function, I don’t see any affect of it. The return is shown as n/a. Do I need to adjust something (thought it was straight copy and paster of above code)?

     

    Thanks.

    • Nicolas • 203 days ago #

      Does your strategy gave result before you add the function? Without seeing the whole code, I can’t help much more, sorry..

  9. arcane • 189 days ago #

    Hello Nicolas

    I raise the subject.

    You can write the code for the actions, if you please

    If you do not have the time, what are the variables to change.

    Can you give a working track.

    Thank you for your help.

    • Nicolas • 189 days ago #

      This code is already compatible with shares. 

  10. Kenneth Kvistad • 138 days ago #

     Does this code work almost the same as break evean code.

    When mef is triggerd does the stop move lets say every 20pips in the favorable direction?  

     

  11. Nacho • 58 days ago #

    Buenas tardes, tengo el sistema activado en la versión original en una cuenta demo desde el día 8 de febrero con la versión 10.3 de proreal y no me coinciden los resultados con el Backtest inicial.

     

  12. Barney • 31 days ago #

    If i want to use the code in the following algo should i add the code

    instead of

    // stop and targets

    OBS. Not a good code.

    If i want trailing stop 5 i only change “Trailingstop = 20” to “Trailingstop = 5” or have i to change something else in the code?

    // Definition of code parameters
    DEFPARAM CumulateOrders = False // Cumulating positions deactivated
    
    // Conditions to enter long positions
    indicator1 = BollingerDown[20](close)
    c1 = (close CROSSES UNDER indicator1)
    
    IF c1 THEN
    BUY 2 CONTRACT AT MARKET
    ENDIF
    
    // Conditions to exit long positions
    indicator2 = Average[20](close)
    indicator3 = Average[50](close)
    c2 = (indicator2 CROSSES OVER indicator3)
    
    IF c2 THEN
    SELL AT MARKET
    ENDIF
    
    // Conditions to enter short positions
    indicator4 = BollingerUp[20](close)
    c3 = (close CROSSES OVER indicator4)
    
    IF c3 THEN
    SELLSHORT 2 CONTRACT AT MARKET
    ENDIF
    
    // Conditions to exit short positions
    indicator5 = Average[50](close)
    indicator6 = Average[20](close)
    c4 = (indicator5 CROSSES UNDER indicator6)
    
    IF c4 THEN
    EXITSHORT AT MARKET
    ENDIF
    
    // Stops and targets
    SET STOP pLOSS 3
    SET TARGET pPROFIT 4
    

     

    • Nicolas • 31 days ago #

      Yes, this code is made to be “plug an play”, but the “trailingstop” variable is the step from the MFE to set the stop order of the trade, it’s not acting like a usual trailingstop.

  13. Barney • 31 days ago #

    Ok, i am going to backtest the MFE code on my algos later today!

    Thanks

avatar
Register or

Top