Your choice of backtest spread can certainly make or break a strategy.
This post will show you how to study the intraday spread variations of your market, and suggest several ways to avoid paying ridiculous spreads.
You can download the Spread Recorder algorithm here.
Have you ever created a strategy that backtests spectacularly, only to see it completely fail in real-time?
You’re certainly not alone.
Unrealistic spread is a very common cause of overly optimistic backtest results.
Here I’ll demonstrate how a low backtest spread can fool you, and offer some suggestions on how to backtest with realistic spreads.
Which Strategies are Most Affected By Spread?
Strategies containing the following characteristics tend to be spread-sensitive:
1. Trades Frequently
Spread is an unavoidable cost per trade. This is one reason why retail traders rarely profit from high-frequency trading techniques.
2. Trades During Illiquid Hours
The Asian session, especially the minutes immediately following the New York close, tends to have the thinnest liquidity. Be wary of enormous spreads at this time.
3. Trades on the Lower Timeframe
On the lower timeframes, your trade exit point, be it a stop loss or an indicator-based value, is likely within 10-20 pips. If you enter the market when spreads are high, you may find yourself immediately within a few pips of your exit.
Let’s check out an Asian scalper that meets the above conditions.
Asian Scalping Gone Wrong
Here’s a mean reversion strategy that uses Keltner Channels and the Laguerre RSI. It typically opens trades shortly after the New York close.
Long are triggered when prices close below the Keltner Channel lower band, accompanied by a dip in the Laguerre RSI.
I did a 15-year backtest on the M15 GBPCAD, using a spread of 2 pips and a slippage of 1 pip. Such transaction costs are generally conservative if you’re using an ECN broker.
Results are spectacular. Are they too good to be true?
I decided to forward test the strategy on a demo account, and alas, a string of losses rapidly ensued. Many trades looked like this:
It’s practically impossible to make a profit with such high spreads. Did I grossly underestimate the spread in my backtest?
Let’s find out!
How to Monitor Current Spreads
Myfxbook lets you monitor live spreads across numerous brokers.
This is a great resource if you’re looking to find the broker with the lowest spreads. But to determine how your market’s spread varies throughout the day, you’ll have to be glued to the screen.
To keep my sanity, I decided to program a simple algorithm that records live spreads. Here’s how you can do it with AlgoWizard.
2. Programming a Spread Recorder with AlgoWizard
First, you need to assign a variable corresponding to spread.
- The IsBarOpen condition means the spread variable will be assigned whenever a new bar opens.
- This is the variable name.
- Select the value to assign to the variable in Step 2. I’ll use Spread in pips, meaning the market spread will be automatically converted to pips, i.e. a 0.0001 spread in GBPCAD means a 1-pip spread.
Next, you’ll need to record the variables.
- This is the filename that contains the variables. Here I’m creating a Notepad file that will be placed in the MQL4 > Files directory of your MT4 data folder.
- This message will appear each time your variable is recorded. +Spread retrieves the spread variable programmed earlier.
I’ll attach the algorithm to a one-minute chart, meaning the spread will be recorded every minute. Here’s how the Notepad output looks like:
Notice there is a comma before the spread value. This comma will help separate the spread when opening the file in Excel.
Let’s now do some Excel analysis.
Analyzing Intraday Spread Variation
I plotted the current spread over a 24-hour period as shown:
Spreads usually stay below 2 pips, except during the 12 – 1 AM window, where spreads skyrocket to over 20 pips. This is when New York has just closed, and Sydney is beginning to open. With few business transactions occurring throughout the world, liquidity is at its lowest point of the day. I zoomed in on the 12 – 1 AM window as shown:
Going from 12 to 1 AM, there is a general decrease in spread, though this is accompanied by large random fluctuations. After 1 AM, spread quickly drops to about 2 pips, and stays there for the rest of the day.
If you do a similar analysis, your results will likely vary, depending on your broker and the day of the week.
With knowledge of how spreads vary throughout the day, how can you arrive at a more realistic backtest spread?
How to Realistically Simulate Backtest Spread
1. Avoid Trading When Spreads Are High
From the GBPCAD data above, the average spread outside the illiquid 12 – 1 AM window is only 1.5 pips. This is actually lower than the 2 pips I specified for the backtest.
In essence, you want to minimize the number of trades closed during illiquid hours, when spreads are much higher and often behave erratically. This is often easier said than done, however.
Apart from your trade entry time, your exit time depends on the type of trade management used. For example, you will likely have an early exit if you use a tight stop loss, or want to hold the trade for only a few bars.
Nonetheless, here are some possible ways to avoid paying high spreads:
a) Use a Spread Entry Filter
This filter will prevent trade entries when the spread exceeds a certain value. You can simply add another entry condition as shown:
b) Use an Intraday Time Filter
This will prevent entries during certain hours of the day.
In the example above, trades will not be opened in the 11 PM – 12 AM window.
c) Disable Your Stop Loss During Illiquid Hours
This will ensure you don’t get stopped out because of spread widening. Of course, this also means your trade will be unprotected, but in the long run you will probably benefit more by avoiding high spreads.
d) Trade a Higher Timeframe
Strategies on higher timeframes usually use wider stop losses (or any price level used for trade management). These are less likely to be triggered by spread widening.
Compared to a 10-pip stop, a 100-pip stop is less likely to be triggered if spreads widen to 20 pips.
2. Use a Higher Backtest Spread
If actively trying to avoid high spreads isn’t your cup of tea, you can increase your backtest spread to account for occasional spread widening.
Determining an appropriate spread is not easy though.
Simply using the 24-hour average spread may not be accurate enough. You need to focus on the trades that are closed during the illiquid hours. These trades will suffer the brunt of the transaction costs.
One option is to determine the proportion of backtest trades that were exposed to high spreads, and increase your backtest spread accordingly. Here’s an example:
I’ll import my MT4 backtest report into QuantAnalyzer and use the Analyze module.
- Select close time so trades will be classified using their closing time (not opening time).
- Toggle Trades by hour to view the number of trades closed during each hour of the day.
In the image above, a large proportion of trades was closed between 12 – 1 AM. It would make sense to increase the backtest spread from 2 pips to say, 4 pips.
Alternatively, your trade distribution may look like this:
In this case, a marginal 0.5 pip increase may be sufficient.
3. Using Monte Carlo Simulations to Vary Spread
As we have seen, spreads are affected by liquidity and can vary significantly in real-time.
Monte Carlo simulations can be used to estimate the effects of variable spread. This involves running the backtest multiple times, each using a different spread.
Here I’ll perform 1000 separate backtest runs on the GBPCAD strategy. For each backtest, a spread between 2-10 pips will be randomly chosen. Since the strategy has a large proportion of trades closing in the 12 – 3 AM window, a 2-10 pip range seems reasonable.
I’ll demonstrate the process using StrategyQuant’s Monte Carlo simulator.
- Select Monte Carlo retest methods in the Retester module.
- This is number of separate backtest runs. I’ll use 1000.
- If your historical data has been broken into in-sample and out-of-sample segments, toggling Full sample means all data segments will be used for backtesting.
- With a Selected timeframe only backtest precision, the OHLC of each M15 bar will be used. A more precise, but much slower, alternative is to use a 1-minute tick simulation, which simulates ticks using 1-minute OHLC (similar to the Every Tick model in MT4).
- Select Randomize spread and input the minimum and maximum values.
Here are the Monte Carlo results of the 1000 backtests.
Since the original backtest used a 2-pip spread, all the Monte Carlo runs will show either similar or worse results.
The equity curves have rather similar shapes because the spreads are static during each of the 1000 runs. This is similar to running backtests with higher commissions.
In actual trading, spread widening can cause premature trade exits, usually because a stop loss is triggered. Depending on your trading frequency, this can drastically change your trade sequence.
To get some actionable numbers from these simulations, let’s use the confidence level table below.
Let’s look at the strategy’s return/drawdown ratio (Ret/DD).
Compared to the original backtest, the Ret/DD at the 95% confidence level has decreased from 12.73 to 1.72. There’s a 5% chance that the actual Ret/DD could be lower than 1.72.
If you want a conservative Ret/DD to use for your backtest, the 95% confidence level is a good choice. This is obviously a huge performance decrease compared to the original value, but spread widening certainly has the potential to destroy a strategy. I’d rather be safe than sorry.
4. Use Tick Data Suite (TDS)
TDS lets you perform MT4 backtests using actual, variable spreads.
I have not used TDS myself, but I have heard plenty of great reviews about it.
If you have a strategy that trades during illiquid hours, it pays to study the intraday spread variations of your market.
The spread recorder algorithm above is a pain-free way to get the data you need with hardly any screen time.
With knowledge of your market’s spread, you can either try to avoid exposure to high spreads, or determine a more conservative value to use for your backtests.