Topic: Protection - Maximum Spread

Hello Traders,

If an Expert advisor is designed to work on a "normal" market, it may not trade well when something unusual happens (like unexpected brexit). Fortunately, it is relatively easy and safe to detect such unexpected market event by monitoring the spread.

Here is how to set a Maximum Spread protection to the expert advisors:


Expert Advisor for MT4

1. Add a Maximum Spread parameter to the expert.

Open the EA in the editor and the following line below the Magic_Number input parameter. It sets default spread protection 25 points. You can change the value in the code or when you run the EA.

static input int Maximum_Spread=25; // Maximum Spread (points)

The code looks like that:

http://s32.postimg.org/3q4fi9cpx/screenshot_1936.png


2. Add a check for the market spread in the ManageOpen function. The following code will check the spread and if it is higher than the input parameter, the "return" command will terminate the position opening.

    if(Ask-Bid>_Point*Maximum_Spread)
      return;

The code will look like that:
http://s32.postimg.org/xqgp4eisl/screenshot_1940.png





Expert Advisor for MT5

1. Add a Maximum Spread parameter to the expert below the Magic_Number input parameter:

static input int Maximum_Spread=25; // Maximum Spread (points)

http://s32.postimg.org/5yrsr2ylh/screenshot_1938.png


2. Add the following check in the ManageOpen function.

   MqlTick tick;
   SymbolInfoTick(_Symbol,tick);
   if(tick.ask-tick.bid>_Point*Maximum_Spread)
      return;

http://s32.postimg.org/cqmt7ocyt/screenshot_1939.png

Re: Protection - Maximum Spread

Hi Popov,

This spread level protection function is already not available? I exported the MT4 EA and opened it to edit, but these texts i dont see in the code. Should i add it same as like here? Or something changed and already not available this function?

Re: Protection - Maximum Spread

Hello Santaferes,

These are modifications you have to made alone.

The code exported from EA Studio is clean and simple. It is designed to allow easy modifications.

This topic is a guide how a trader to modify his export in order to implement Spread protection.

Re: Protection - Maximum Spread

just to confirm

this EA modification, works with portfolios?

Re: Protection - Maximum Spread

I wanted to set a criteria ... if spread is greater than allowable spread, don't trade.

Is this post still relevant ?  I couldn't find ManageOpen in the EA generated by FSB Pro.

If this post is no long relevant, what is the open logic that I can use to prevent trading when spread is too high ?

Re: Protection - Maximum Spread

This thread is for the Expert Advisor Studio experts.

You don't need this for FSB Pro. You can do it there with the Spread Level Pro indicator.

7 (edited by ChristianS 2017-12-29 22:21:54)

Re: Protection - Maximum Spread

Hi, the idea is great to protect the EA when spread arise.

In the EA studio export I found the coding insert place:  ManageOpen() function, BUT what is with the EA studio portfolio?

In only found the function for every strategy Signal GetEntrySignal_01(), can I use the same coding block for spread protection for every strategy in the EA portfolio or is there a better coding way? For example maybe in the void SetSignals(Signal &signalList[]) ?

Any idea? Thanks Chris

Re: Protection - Maximum Spread

https://s9.postimg.org/50171xll7/EAS-_Manage_Signal-572x398.png

There is a function called ManageSignal() -- I've added code there to check for certain conditions and it seems to work fine.  If you place your code within the 'if' condition then it will only affect the opening of new positions -- which is probably what you want.

Re: Protection - Maximum Spread

Great, thanks for your input.

So for the EA studio portfolio we can insert for maximum spread this solution:

static input int    Maximum_Spread     = 25; // Maximum Spread (points)

and add in the function void ManageSignal(Signal &signal)

Position position=CreatePosition(signal.MagicNumber);
   if(position.Type==OP_FLAT && signal.Scope==ORDER_SCOPE_ENTRY)
     {
       //Add protection maximum spread
      if(Ask-Bid>_Point*Maximum_Spread)
      return; 
      
      
      if(signal.Direction==ORDER_DIRECTION_BUY ||
         signal.Direction==ORDER_DIRECTION_SELL)
         if (OrdersTotal()<MaxTrades) {
         OpenPosition(signal);}
     }

Re: Protection - Maximum Spread

Yes -- I believe that is the idea, though I'm not prepared to guarantee that is the only or most correct solution.  However, that would be the first thing I would try.

Also, it goes without saying, this needs to be tested.  It should be relatively easy -- e.g. you could use MT4's Strategy Tester and experiment with changing the Spread's input parameter.

Re: Protection - Maximum Spread

What to do that i get a comment in journal that spread is too high?

Re: Protection - Maximum Spread

Something like that.

const double spread = (Ask - Bid) / _Point;
if (spread > Maximum_Spread)
{
    Print("The current spread", DoubleToString(spread, 0), "is higher than the maximum allowed.");
    return;
}

13 (edited by Popov 2018-03-27 19:31:03)

Re: Protection - Maximum Spread

This is working for mt4 but the mt5 code not work. can you check with a print function

14 (edited by deadlef 2018-03-27 20:46:23)

Re: Protection - Maximum Spread

deadlef wrote:

This is working for mt4 but the mt5 code not work. can you check with a print function

Just checked again if i add this to mq5 file.

 MqlTick tick;
   SymbolInfoTick(_Symbol,tick);
   if(tick.ask-tick.bid>_Point*Maximum_Spread)
      return;

it looks working well..but when i add this with a comment in journal

 MqlTick tick;
   SymbolInfoTick(_Symbol,tick);
   if(tick.ask-tick.bid>_Point*Maximum_Spread)
{
Print("The current spread is higher than the maximum allowed.");
}
return;

it doesnt work..can someone help me out

Re: Protection - Maximum Spread

Your code is correct. This is the way MT provide Bid and Ask prices needed for calculating the real spread.

Re: Protection - Maximum Spread

Something is wrong here.

First i set Max Spread to 50. The Gold Spread currently is 200.
https://s14.postimg.org/p7oumqu6l/set1.png
Now the results. Here looks okay.
https://s14.postimg.org/ytif2kvhp/res1.png

Now i set Max Spread to 300. The Gold Spread currently is 200.
https://s14.postimg.org/5ecqtmoe5/set2.png

And now there is something wrong. Now it must trade but this is in journal and make no trades.
And this i have checked with EURUSD and other pairs.
https://s14.postimg.org/eywdgkqlp/res2.png

Re: Protection - Maximum Spread

The "return;" in you second code must be inside the braces.

Re: Protection - Maximum Spread

Hi All,

Has this Portfolio spread protection code by ChristianS been tested for performance, anyone??

ChristianS wrote:

Great, thanks for your input.

So for the EA studio portfolio we can insert for maximum spread this solution:

static input int    Maximum_Spread     = 25; // Maximum Spread (points)

and add in the function void ManageSignal(Signal &signal)

Position position=CreatePosition(signal.MagicNumber);
   if(position.Type==OP_FLAT && signal.Scope==ORDER_SCOPE_ENTRY)
     {
       //Add protection maximum spread
      if(Ask-Bid>_Point*Maximum_Spread)
      return; 
      
      
      if(signal.Direction==ORDER_DIRECTION_BUY ||
         signal.Direction==ORDER_DIRECTION_SELL)
         if (OrdersTotal()<MaxTrades) {
         OpenPosition(signal);}
     }

Re: Protection - Maximum Spread

bisentim wrote:

Hi All,

Has this Portfolio spread protection code by ChristianS been tested for performance, anyone??

ChristianS wrote:

Great, thanks for your input.

So for the EA studio portfolio we can insert for maximum spread this solution:

static input int    Maximum_Spread     = 25; // Maximum Spread (points)

and add in the function void ManageSignal(Signal &signal)

Position position=CreatePosition(signal.MagicNumber);
   if(position.Type==OP_FLAT && signal.Scope==ORDER_SCOPE_ENTRY)
     {
       //Add protection maximum spread
      if(Ask-Bid>_Point*Maximum_Spread)
      return; 
      
      
      if(signal.Direction==ORDER_DIRECTION_BUY ||
         signal.Direction==ORDER_DIRECTION_SELL)
         if (OrdersTotal()<MaxTrades) {
         OpenPosition(signal);}
     }

This should not work correctly. Sometimes it is opening trades.
I put it into this code section and it is working.

void OpenPosition(Signal &signal)
  {
       //Add protection maximum spread
      if(Ask-Bid>_Point*Maximum_Spread)
      return; 

20 (edited by geektrader 2019-01-16 22:49:51)

Re: Protection - Maximum Spread

Hi Popov,

don´t you think it would make sense to add such a spread-protection to the exported MT4 / MT5 code by default? You could set it to "0" as default (disabled) or 99999, so only people that want to use it can use it. I think that´s more new-user-friendly than having them modify the code on their own, as especially new users are not comfortable with that and just want a working strategy exported, but still will need spread-protection as it surely makes no sense to open a trade if the backtest was done at 1 pip spread and then there is a spread spike to 20 pips (for whatever reason) and their order gets messed up right from the start as it enters at such a high spread.

In terms of usability and to get more subscriptions, that really might be a good idea - keeping it easy (but expendable for experienced users) is always the best way to get as many users as possible.

21 (edited by geektrader 2019-01-17 01:22:54)

Re: Protection - Maximum Spread

In case you can add this to the default code that EA Studio exports, I´ve written an implementation that follows your coding style (I hope, haha) that you can use. Add this:

Input parameters section:

input int           Maximum_Spread_Points = 0;

To the OpenPosition function (need to add it there as we want to be able to tell if the EA tried to place a trade during the time the spread was to high or not):

void OpenPosition(int command)
{
    if (!IsWithinMaxSpread())
        return;

        [EXISTING CODE FROM HERE ON]

And a new function at the end of the MQ4 code:

bool IsWithinMaxSpread()
{
    bool WithinMaxSpread = true;

    if (Maximum_Spread_Points > 0)
    {
        double spread = NormalizeDouble(((Ask - Bid) / _Point), 0);
        //Need NormalizeDouble here because of rounding errors in MT4 that otherwise occur (confirmed in several backtests).

        if (spread > Maximum_Spread_Points)
        {
            Print("The current spread of ", DoubleToString(spread, 0), " points, is higher than the maximum allowed of ", DoubleToString(Maximum_Spread_Points, 0), " points. Skipping trade!");
            WithinMaxSpread = false;
        }
    }

    return(WithinMaxSpread);
}

Example validation-output (backtest and live tested)

2019.01.17 01:19:39.190    2018.09.26 05:00:00  10000000 SuperStrat GBPJPY H1 GBPJPY,H1: The current spread of 7 points, is higher than the maximum allowed of 6 points. Skipping trade!
2019.01.17 01:19:39.190    2018.09.25 13:00:00  10000000 SuperStrat GBPJPY H1 GBPJPY,H1: The current spread of 7 points, is higher than the maximum allowed of 6 points. Skipping trade!
2019.01.17 01:19:39.189    2018.09.24 04:00:00  10000000 SuperStrat GBPJPY H1 GBPJPY,H1: The current spread of 7 points, is higher than the maximum allowed of 6 points. Skipping trade!
2019.01.17 01:19:39.189    2018.09.20 03:00:00  10000000 SuperStrat GBPJPY H1 GBPJPY,H1: The current spread of 7 points, is higher than the maximum allowed of 6 points. Skipping trade!
2019.01.17 01:19:39.189    2018.09.19 18:00:00  10000000 SuperStrat GBPJPY H1 GBPJPY,H1: The current spread of 7 points, is higher than the maximum allowed of 6 points. Skipping trade!

Note that "Maximum_Spread_Points" is default at 0, which means the protection is disabled. Only if it is > 0, it will be used. This way you can default turn it off by leaving it at 0 if freshly exported from EA Studio and users can turn it on only if they really need it ;-)

By the amount of views this forum thread has (it is the second most viewed after "auto lot size calculation"), I can tell that people really seem to be looking for this feature in EA Studio "out of the box" and I´d say it´s a feature that every serious trader really NEEDS to use to protect from "catastrophic" entries that can kill the account in the worst case. if you just think Brexit / black swan events (CHF comes to mind) where we had spreads > 500 pips at times, it would be fatal to enter a trade at that spread and, if trading bigger amounts, can cost you a few thousand dollars or more quickly as right when you enter the trade you will be at -500 pips loss. And if that happens, EA Studio´s MT4 code will also not be able to set the stop loss (in case it´s < 500 pips) and the trade would go completely uncontrolled from there, not even having a stop loss (and this, by the way, is another feature you should think about: if the EA is unable to set a stop loss to a just opened position after say 3 times, it should close it right away as something BAD just happened - I have that in my own EAs all the time. Yes, one might think I am paranoid, but it´s a bit like driving without a seat belt, usually you never need it, but that one time you didn´t use it, can cost your life, or in this case, your whole account). Hence I think that the spread protection feature should be a *standard* in any serious platform / for any serious trader that does not just trade on demo.

Re: Protection - Maximum Spread

I´ve advanced the function a bit to retry a few times if spread might possibly change below our threshold. If you want to use that, here it is:

bool IsWithinMaxSpread()
{
    bool WithinMaxSpread = true;

    for (int attempt = 0; attempt < TRADE_RETRY_COUNT; attempt++)
    {
        RefreshRates();
        WithinMaxSpread = true;

        if (Maximum_Spread_Points > 0)
        {
            double spread = NormalizeDouble(((Ask - Bid) / _Point), 0);
            //Need NormalizeDouble here because of rounding errors in MT4 that otherwise occur (confirmed in several backtests).

            if (spread > Maximum_Spread_Points)
            {
                Print("The current spread of ", DoubleToString(spread, 0), " points, is higher than the maximum allowed of ", DoubleToString(Maximum_Spread_Points, 0), " points. Try ", IntegerToString(attempt + 1), " of ", IntegerToString(TRADE_RETRY_COUNT), ".");
                WithinMaxSpread = false;
            }
        }
        Sleep(TRADE_RETRY_WAIT);
    }
    
    return(WithinMaxSpread);
}

Re: Protection - Maximum Spread

geektrader wrote:

I´ve advanced the function a bit to retry a few times if spread might possibly change below our threshold. If you want to use that, here it is:

bool IsWithinMaxSpread()
{
    bool WithinMaxSpread = true;

    for (int attempt = 0; attempt < TRADE_RETRY_COUNT; attempt++)
    {
        RefreshRates();
        WithinMaxSpread = true;

        if (Maximum_Spread_Points > 0)
        {
            double spread = NormalizeDouble(((Ask - Bid) / _Point), 0);
            //Need NormalizeDouble here because of rounding errors in MT4 that otherwise occur (confirmed in several backtests).

            if (spread > Maximum_Spread_Points)
            {
                Print("The current spread of ", DoubleToString(spread, 0), " points, is higher than the maximum allowed of ", DoubleToString(Maximum_Spread_Points, 0), " points. Try ", IntegerToString(attempt + 1), " of ", IntegerToString(TRADE_RETRY_COUNT), ".");
                WithinMaxSpread = false;
            }
        }
        Sleep(TRADE_RETRY_WAIT);
    }
    
    return(WithinMaxSpread);
}

Hi Geek, just wondering where in this code can I put how many times to retry the trade?
Where can I put how long to sleep for before retrying?

Re: Protection - Maximum Spread

i can find that in code. just look at top

#define TRADE_RETRY_COUNT 4
#define TRADE_RETRY_WAIT  100

Re: Protection - Maximum Spread

Roughey wrote:

i can find that in code. just look at top

#define TRADE_RETRY_COUNT 4
#define TRADE_RETRY_WAIT  100

Thanks mate maybe I should look a bit harder