Sell in May, seven ways

Own seven of the world's stock markets from November to April, then sit in cash until October. Over fifty-five years this grew $1 into $19.70 while the worst fall was a third of the account — against $36.80 and a loss of nearly two-thirds for simply staying invested.

Conclusion: Validated

Passed all six checks. Indicative performance of 5.4% a year is 1.1 points below the 6.5% returned by holding the same universe continuously, return for risk taken sits at 0.58 against the benchmark's 0.47, and the worst fall of 36.1% is 25.8 points below the benchmark's 61.9%. Exposure was held in 330 of 656 months.

Figure 1 · Growth of $1

1971–2026 · net of 15bp round-trip costs
What one dollar became, after costs: $19.27 by 2026. Shown against Control, S&P 500, rebased to the same starting dollar.
Return for risk
0.58
range 0.32 to 0.85
Ann. return
5.4%
volatility 9.3%
Max drawdown
36.1%
over 656 months
Beats the search
25.6%
chance, after correction

Method

Hypothesis

Equity returns concentrate in November–April. A basket that sits flat over May–October earns a better risk-adjusted return than one continuously invested.

Rule

UNIVERSE = [^GSPC ^N225 ^AXJO ^BVSP ^NSEI ^KLSE ^NZ50]
IN_SEASON = [Nov Dec Jan Feb Mar Apr]
VOL_WINDOW = 36 months
function positions(bar):
if month(bar.next) not in IN_SEASON:
return {} # hold nothing through the northern summer
return equal_risk(UNIVERSE, bar)
function equal_risk(symbols, bar):
for symbol in symbols:
vol = stdev(returns(symbol, VOL_WINDOW, ending bar.prev))
w[symbol] = 1 / vol # smaller position in a wilder market
return w
# ── execution ────────────────────────────────────────────────────────
COST_PER_TRADE = 15 bps of the notional that changes hands
function on_bar(bar, book):
if not bar.is_month_end:
return # decisions are made monthly only
target = positions(bar) # the rule above
target = scale_to_gross(target, 1.0)
rebalance(book, target, bar)
function scale_to_gross(w, limit):
gross = sum(abs(w)) # total capital at work
if gross == 0:
return w # flat is a valid target
return w * limit / gross # leverage fixed, never implicit
function rebalance(book, target, bar):
for symbol in union(book.symbols, target.symbols):
delta = target[symbol] - book.weight(symbol)
if delta > 0:
buy(symbol, delta, fill = next_bar.close)
else if delta < 0:
sell(symbol, -delta, fill = next_bar.close)
book.charge(COST_PER_TRADE * abs(delta))
# Orders are filled at the next month's close, never the one the decision
# was made on. There is no stop_loss(), take_profit(), limit order or
# position cap: a holding changes only when positions() returns a
# different target at the next month end.

Analysis

Basis for inclusion

Two researchers, Bouman and Jacobsen, found this pattern in 36 of 37 countries in 2002. Most calendar patterns vanish once people know about them. This one has not: a later study traced it back three centuries in British data.

That history is why it was allowed in here. It was not found by rummaging through this dataset until something turned up. It was already on the record, and this is a check of it.

The rule is deliberately blunt. If the effect is real, it should show up in the simplest version of the idea, not only in a carefully tuned one.

Evidence

It passes every test. Measured against the same basket held all year, it earns a better return for the risk taken, and its worst fall is a third of the account rather than two-thirds. The profit is spread across the years rather than arriving in a lucky handful of months.

There is no mystery in how it works. The strategy is invested about half the time and sits out the worse half. Less exposure means smaller losses, and a better return per unit of risk follows from that alone.

Qualifications

A dollar becomes $19.70 here, against $36.80 for simply staying invested. The better risk-adjusted return never turns into more money. To convert it you would have to borrow in order to take the same risk as the plain approach, and borrowing costs money that this test does not charge.

The last decade also reverses the comparison. Over the whole history the strategy leads; over 2015 to 2026 alone, staying invested wins. A strategy whose job is to avoid trouble does badly in a decade with little trouble in it.

One caveat runs the other way. These indices exclude dividends, and the strategy's idle cash earns nothing here. In reality the cash would earn interest, and over this period interest was worth more than the dividends given up. The test is harder on the strategy than reality would be.

A higher Sharpe that cannot be levered is a smoother path to a smaller number.

Evaluation

Table 1 · Performance

1971-11 – 2026-06 · 656 months, 330 invested
MeasureValue
Annualised return5.4%
Annualised volatility9.3%
Return for risk taken0.58
95% range0.32 to 0.85
t-statistic4.32
Maximum drawdown36.1%
Hit rate63.6%
Annual turnover2.07×
Return skew(0.09)
Return kurtosis10.62
The range is measured by resampling the history in blocks, so runs of good and bad months stay intact.

Table 2 · Robustness

DiagnosticValueReads asBadOkayYayHmm
Design half (pre-2015)0.64return for risk≤ 00 – 0.40≥ 0.40
Holdout half (2015+)0.36return for risk≤ 00 – 0.40≥ 0.40
Top-5-month share of profit18.7%how much rode on a few months — lower is better≥ 40%25 – 40%< 25%
Top-2-year share of profit17.7%concentration
Distinct trading episodes55how many independent runs this really is< 5050 – 100≥ 100
Chance the edge is real100.0%non-normality corrected
Chance it beats the whole search25.6%chance of beating the whole search by luck
bad/ok boundary is the pre-registered criterion · ok/good is a margin above it, not a criterion · blank where none was registered
The last row asks whether the result would stand out from the hundred-odd ideas tried here, rather than being judged alone.

Table 3 · Pre-registered criteria

measured against C6_RP_IDX
1PASS2PASS3PASS4PASS5PASS6PASS
CheckWhat it asksResult
1Reward large enough for the riskpass
2Confidence range clear of zeropass
3Profit not concentrated in a few monthspass
4Worked in both halves of the historypass
5Beat buying and holdingpass
6Stood out from the whole searchpass
These six checks were written down before the strategy was run.

Table 4 · Net return by calendar year

after costs
+27%-27%
YearNet return
19717.9%
197210.7%
1973(20.6%)
1974(15.5%)
197525.1%
197616.0%
1977(6.1%)
19784.6%
197911.2%
19804.5%
1981(2.0%)
1982(0.4%)
198316.2%
1984(2.6%)
198517.7%
19869.8%
198715.3%
19884.9%
198914.3%
19901.4%
199118.6%
19923.2%
19930.4%
1994(8.6%)
199513.1%
199612.8%
19977.3%
199820.1%
199927.1%
2000(4.9%)
20016.8%
2002(1.1%)
20035.5%
20047.9%
20050.5%
200615.2%
20074.4%
2008(12.4%)
200910.1%
20103.4%
2011(1.1%)
201210.5%
20135.4%
20142.2%
20154.1%
20162.7%
201710.0%
20180.0%
201911.9%
2020(3.8%)
20212.6%
2022(3.5%)
202310.8%
20242.7%
2025(0.7%)
20260.5%

Table 5 · Concentration detail

MeasureValue
Best years1999:+27%, 1975:+25%, 1998:+20%
Worst year1973:-21%

Reference

Instruments

last price and one-month change, live from Yahoo Finance
SymbolNotes
^GSPCS&P 500 — market index, in USD.
^N225Nikkei 225 — market index, in JPY.
^AXJOS&P/ASX 200 — market index, in AUD.
^BVSPIBOVESPA — market index, in BRL.
^NSEINIFTY 50 — market index, in INR.
^KLSEFTSE Bursa Malaysia KLCI — market index, in MYR.
^NZ50S&P/NZX 50 Gross — market index, in NZD.
CASHPathward Financial Inc. — listed on NasdaqGS, in USD.

Sample

1971-11 – 2026-06 · 656 months

Sources

NOAA Physical Sciences Laboratory. Climate indices. ONI, Niño 3.4, MEI v2, DMI, PDO, AMO, TNA, QBO, solar flux. psl.noaa.gov/data/climateindices/list
Queensland Department of Agriculture and Fisheries. Southern Oscillation Index. The Long Paddock. Monthly, 1876–. www.longpaddock.qld.gov.au/soi/soi-data-files
Yahoo Finance. Historical market prices. Adjusted close, month-end. Retrieved with yfinance. finance.yahoo.com

Revision history

RevStageStatusChange
01DraftDirection and criteria fixed before the experiment ran
02TestedValidatedCleared every criterion
algorithmic-trading-anthology-july-2026-halloween-seven-index | d/rksci