The effects of dodging the worst days

In which we examine how our bottom line changes if we were able to avoid the worst trading days

A bad day in the markets
A bad day in the markets

Fidelity has previously published ideas for disciplined investors, looking at the effects of missing the markets’ best performing days. In short, missing the top 10 days cuts your investment returns in half. This should put the buy and hold investor at ease holding their assets through volatile periods. The research is available here.

But what about holding through the worst performing days in the market? How much are we sabotaging our portfolios by holding when the market is losing ground?

Let’s look at the returns of various ETFs.

First we need to load some data. For this purpose, we’ll examine the last 15 years. That’s about the number of years that I could have been investing.

val logger = LoggerFactory.getLogger(etf.ticker)
val startDate = LocalDateTime.now().minusYears(15)
val data = loader.download(etf).dropWhile { it.datetime.isBefore(startDate) }

First we create a logger to communicate our results. Then we define the research period to be 15 years. And finally we download the ETF data and drop all rows before our start date.

Next we want to get access to the close prices of the asset.

val closePrices = data.map { it.close.toDouble() }
closePrices.toChart()

SPY

We’re not interested in the nominal value but rather in the daily returns of the ETF.

val dailyReturns = closePrices.asReturns()
dailyReturns.toChart()

SPY daily returns

Moving on, we’d like to create an equity curve representing a $10,000 buy and hold investment. This is the equity curve that we’ll use as a baseline.

val equity = dailyReturns.equityCurve(10_000.0)

And now the important bit - we’d like another equity curve with $10,000 invested, but this time we’ll remove the 10 worst trading days from the data.

val topLosers = dailyReturns.sorted().take(10)
val returnsWithoutTopLosers = dailyReturns.filter { !topLosers.contains(it) }
val equityWithoutTopLosers = returnsWithoutTopLosers.equityCurve(10_000.0)

Let’s see it

val dataset = listOf(
    equity.toXYSeries("Buy & Hold"),
    equityWithoutTopLosers.toXYSeries("Removed worst losers")
).toDataset()
dataset.toChart()

SPY without its worst losing days

SPY - Buy and hold: 30136
SPY - Without top losers: 71134

This pattern holds true for other ETFs:

QQQ without its worst losing days

QQQ - Buy and hold: 75613
QQQ - Without top losers: 165811

IWM without its worst losing days

IWM - Buy and hold: 31591
IWM - Without top losers: 85848

Now if there was only a way to predict the worst market days…

Historical research from the Algogen archive. Not investment advice.

Blog

Have a strategy idea?

Describe it in plain English, preview where your rules fire, then decide whether the evidence is worth a backtest.

Try with my idea → Sign in