Sell in May and Go Away dey work?
Sell in May and Go Away don face two decades of S&P 500 seasons. See summer gap wey dey small and wetin this seasonal switch fit cost for real life.
Sell in May and go away na the calendar rule wey people know pass for stock market: sell for end of April, keep cash throughout summer, then buy back for end of October. When dem measure S&P 500 tracker prices from the last April 2005 close reach the last April 2026 close, the November to April half of the year dey record higher average return than the May to October half. The gap dey real, but e small pass wetin the saying imply. The summer half sef dey record average gain, and na here the rule no work well as investment plan.
Rule talk wetin, and how you fit test am
This phrase come from one old London habit: people dey leave town after the spring race meetings and come back for autumn. For the modern version wey person fit test, na switching rule with two dates. You hold broad stock index from the last trading day for October reach the last trading day for April. For the other six months, you no hold anything.
To test am, you need two things wey the saying itself no provide: price series and clear test window. Every number below use SPY, the oldest S&P 500 exchange traded fund, with price from regular-hours minute bars for the global_markets.delayed_stocks_minute_aggs table. The period run from the final April 2005 close reach the final April 2026 close. For this article, monthly return na the last regular-hours price compared with the previous month’s price only. Dividends get their own section further down, and how wey dem dey measure monthly returns explain why this difference dey change the answer.
Sell for May, come back later — e record from 2005 to 2026
The exact SQL behind every number
WITH monthly AS (
SELECT toStartOfMonth(toDate(toTimeZone(window_start, 'America/New_York'))) AS month_start,
argMax(close, window_start) AS month_close
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2005-04-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-04-30')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY month_start
)
SELECT toYear(apr_m.month_start) AS year,
round(100 * (toFloat64(oct_m.month_close) / toFloat64(apr_m.month_close) - 1), 2) AS may_oct_pct,
round(100 * (toFloat64(apr_next.month_close) / toFloat64(oct_m.month_close) - 1), 2) AS nov_apr_pct
FROM monthly AS apr_m
INNER JOIN monthly AS oct_m ON oct_m.month_start = addMonths(apr_m.month_start, 6)
INNER JOIN monthly AS apr_next ON apr_next.month_start = addMonths(apr_m.month_start, 12)
WHERE toMonth(apr_m.month_start) = 4
ORDER BY yearEach point dey pair one summer with the winter wey follow am. Chart get 21 complete pairs, e start with summer of 2005 and close with winter wey end for April 2026.
The two lines no agree for most individual years, and dem agree for the worst one. Between end of April and end of October 2008, the summer half measure -29.81%, wey be the deepest reading for the whole run. The winter wey follow measure -10.03%. Person wey sell for that April avoid one heavy fall, then enter again for the final leg down. Calendar and the damage match for only half of the journey.
Summer gap don fade since 2015?
Na averages be wetin the saying really dey claim, and the period na wetin those averages dey rest on. If we split the run for 2015, we get two halves wey almost get the same length, and we calculate both the same way.
The exact SQL behind every number
WITH monthly AS (
SELECT toStartOfMonth(toDate(toTimeZone(window_start, 'America/New_York'))) AS month_start,
argMax(close, window_start) AS month_close
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2005-04-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-04-30')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY month_start
),
pairs AS (
SELECT toYear(apr_m.month_start) AS season_year,
toFloat64(oct_m.month_close) / toFloat64(apr_m.month_close) - 1 AS may_oct,
toFloat64(apr_next.month_close) / toFloat64(oct_m.month_close) - 1 AS nov_apr
FROM monthly AS apr_m
INNER JOIN monthly AS oct_m ON oct_m.month_start = addMonths(apr_m.month_start, 6)
INNER JOIN monthly AS apr_next ON apr_next.month_start = addMonths(apr_m.month_start, 12)
WHERE toMonth(apr_m.month_start) = 4
),
tagged AS (
SELECT may_oct,
nov_apr,
arrayJoin(['All seasons 2005-2025',
if(season_year <= 2014, 'First half 2005-2014', 'Second half 2015-2025')]) AS era
FROM pairs
)
SELECT era,
count() AS season_count,
round(100 * avg(may_oct), 2) AS avg_may_oct_pct,
round(100 * avg(nov_apr), 2) AS avg_nov_apr_pct,
round(100 * (avg(nov_apr) - avg(may_oct)), 2) AS winter_minus_summer_pct,
countIf(may_oct > 0) AS summers_positive
FROM tagged
GROUP BY era
ORDER BY eraAcross all 21 seasons, May to October average 3.88%, while November to April average 6.06%. That one make spread of 2.18 percentage points. Na this spread carry the whole argument for the rule. Look the summer column beside am: 16 of those summers end higher than where dem start. So, the average sit-out miss gain, no be loss.
The two halves no match. The earlier block show spread of 4.84 points, while the later one show -0.24. Popular retellings dey quote gap without naming the years behind am, but na the years be the argument. Every seasonal statistic na claim about one period for history, and na the person wey dey repeat am choose the period.
Na the August and September effect really be?
Six months na blunt instrument. If we break calendar into months, e go show whether summer window soft all through or whether na one part dey carry the whole result.
The exact SQL behind every number
WITH monthly AS (
SELECT toStartOfMonth(toDate(toTimeZone(window_start, 'America/New_York'))) AS month_start,
argMax(close, window_start) AS month_close
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2005-04-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-04-30')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY month_start
),
month_returns AS (
SELECT m1.month_start AS month_start,
100 * (toFloat64(m1.month_close) / toFloat64(m0.month_close) - 1) AS ret_pct
FROM monthly AS m1
INNER JOIN monthly AS m0 ON m0.month_start = addMonths(m1.month_start, -1)
)
SELECT formatDateTime(month_start, '%b') AS label,
count() AS readings,
round(avg(ret_pct), 2) AS avg_return_pct,
round(quantileDeterministic(0.5)(ret_pct, cityHash64(month_start)), 2) AS median_return_pct,
countIf(ret_pct > 0) AS positive_readings
FROM month_returns
GROUP BY label
ORDER BY min(toMonth(month_start))Na September weakness dey show. E average -0.75% and finish higher for 12 out of 21 years, with median of 0.38%. August average 0.28%. July, wey dey middle of the period wey seller dey skip, average 2.63%. October, wey be the last month before the rule buy back, average 0.97%.
The effect for this window narrow: one weak patch late for summer, while the months around am look almost like the rest of the calendar. If person exit at the end of April to miss September, e still miss May, June, July and August.
Wetin the switch really dey cost
The seasonal gap na gross number. Any rule must survive the costs wey come with am.
The exact SQL behind every number
WITH monthly AS (
SELECT toStartOfMonth(toDate(toTimeZone(window_start, 'America/New_York'))) AS month_start,
argMax(close, window_start) AS month_close
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2005-04-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-04-30')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY month_start
),
pairs AS (
SELECT toYear(apr_m.month_start) + 1 AS year,
toFloat64(oct_m.month_close) / toFloat64(apr_m.month_close) AS summer_ratio,
toFloat64(apr_next.month_close) / toFloat64(oct_m.month_close) AS winter_ratio
FROM monthly AS apr_m
INNER JOIN monthly AS oct_m ON oct_m.month_start = addMonths(apr_m.month_start, 6)
INNER JOIN monthly AS apr_next ON apr_next.month_start = addMonths(apr_m.month_start, 12)
WHERE toMonth(apr_m.month_start) = 4
)
SELECT year,
round(exp(sum(log(summer_ratio * winter_ratio)) OVER (ORDER BY year)), 2) AS buy_and_hold_growth,
round(exp(sum(log(winter_ratio)) OVER (ORDER BY year)), 2) AS winter_only_growth
FROM pairs
ORDER BY yearOne dollar wey stay invested through every season from the end of April 2005 grow reach $6.21 by the end of April 2026. The same dollar wey stay for market only from November reach April, and remain idle for the rest of the time, grow reach $3.14. Both lines na price only, with no cost removed, so dem make the switching rule look better than e fit be. These na the things wey the chart no show.
- Two trades every year, for each of the 21 seasons. Most brokers no dey charge ticket fee again. But the bid-ask spread wey you pay for each round trip still dey.
- Tax. For taxable account, the April sale go realize any gain wey build up since November. By design, November-to-April holding period no reach one year, so US taxpayer go face short-term rates on the gain.
- Idle cash. The winter-only line assume say the money wey remain outside market earn zero. Real investor fit park the money, and where to park idle cash explain the instruments people dey use for that.
- Dividends, wey the next panel calculate.
The exact SQL behind every number
SELECT toYear(ex_dividend_date) AS year,
round(sumIf(cash_amount, toMonth(ex_dividend_date) >= 5 AND toMonth(ex_dividend_date) <= 10), 3) AS may_oct_dividends_usd,
round(sumIf(cash_amount, toMonth(ex_dividend_date) < 5 OR toMonth(ex_dividend_date) > 10), 3) AS nov_apr_dividends_usd
FROM global_markets.stocks_dividends
WHERE ticker = 'SPY'
AND cash_amount > 0
AND ex_dividend_date >= toDate('2005-01-01')
AND ex_dividend_date <= toDate('2025-12-31')
GROUP BY year
ORDER BY yearSPY ex-dividend dates dey fall for March, June, September and December. So two of the four dates dey inside the six months wey seller stay outside market. For 2025, distributions of $3.592 per share get May-to-October ex-date, compared with $3.689 for the other six months. The two columns dey follow each other across the whole chart. Staying outside market for half the calendar year means say investor dey miss roughly half of the fund’s income every year, on top of wetin price do during those months. The ex-dividend date na the cutoff wey determine who go receive payment.
One more cost no dey show as separate line item. Index returns dey come in clusters, and missing the best days show wetin just a few missed sessions fit do to long-run balance. Six months outside market every year mean plenty missed sessions. Na the same calculation behind dollar cost averaging as a discipline about time inside market, instead of trying to time the market.
Why person need suspect one famous calendar rule
Twelve months get 4,095 different ways to choose a non-empty subset wey go get investment. If you search all those combinations against one price history, something go surely look striking. Na the search itself cause am.
Sell in May get one honest advantage over rule wey person mine last week: e famous before this sample start, so the years for this page work as out-of-sample test, no be fitted result. The test show small gap, and most of am dey come from one month. E dey follow switching rule wey underperform buying and holding across the same period. Look-ahead bias explain how backtest fit quietly learn the answer before time, and calendar rules na textbook example: dem pick the months after dem don already know the returns.
FAQ
Sell for May come out, still dey work?
For SPY prices from April 2005 reach April 2026, November reach April average 6.06% against 3.88% for May reach October. So, the seasonal gap still dey show for the full sample. The summer half still average gain, and 16 out of 21 summers finish higher than where dem start.
Which months really weak?
For this period, the weakness dey mostly for September. September average -0.75% and finish higher for 12 out of 21 years. July, another month wey the rule avoid, average 2.63% for the same period.
Selling for May dey beat buying and holding?
No be for this sample. One dollar wey person hold continuously from end of April 2005 grow reach $6.21 by April 2026. The winter-only switch grow reach $3.14. This comparison no include trading costs, tax, or dividends.
Wetin happen to dividends if you sell for May?
Fund ex-dividend dates no dey stop for summer. Two out of SPY four quarterly ex-dividend dates dey inside the May to October period. Person wey no dey hold the fund on an ex-dividend date no go receive that distribution.
Seasonal pattern na the same thing as prediction?
No. Historical average across 21 seasons only describe wetin happen for the stated period. Individual years fit move far from that average, as the first chart show. The period itself na choice.
Every panel for here na stored query with the SQL attached. Change the ticker, adjust the period, and check whether the seasonal gap still hold for the Strasmore terminal.