Does Sell in May and Go Away Work?
Growth of one dollar: holding all year vs holding only November through Aprilranking ·
2026-08-03 · 21×3
The seasonal gap by era: average half-year returns and the spread between themtable ·
2026-08-03 · 3×6
S&P 500 tracker: May to October vs November to April, season by seasonranking ·
2026-08-03 · 21×3
Average S&P 500 tracker return by calendar month, May 2005 through April 2026table ·
2026-08-03 · 12×5
SPY distributions by ex-dividend month: inside the May to October window vs outside itranking ·
2026-08-03 · 19×3
Growth of one dollar: holding all year vs holding only November through April
Growth of one dollar: holding all year vs holding only November through April
| year | buy_and_hold_growth | winter_only_growth |
|---|---|---|
| 2006 | 1.13 | 1.09 |
| 2007 | 1.28 | 1.17 |
| 2008 | 1.2 | 1.05 |
| 2009 | 0.76 | 0.94 |
| 2010 | 1.03 | 1.08 |
| 2011 | 1.18 | 1.24 |
| 2012 | 1.21 | 1.39 |
| 2013 | 1.38 | 1.57 |
| 2014 | 1.63 | 1.68 |
| 2015 | 1.8 | 1.74 |
| 2016 | 1.78 | 1.72 |
| 2017 | 2.06 | 1.93 |
| 2018 | 2.29 | 1.99 |
| 2019 | 2.54 | 2.16 |
| 2020 | 2.51 | 2.06 |
| 2021 | 3.61 | 2.64 |
| 2022 | 3.56 | 2.37 |
| 2023 | 3.59 | 2.55 |
| 2024 | 4.34 | 3.06 |
| 2025 | 4.79 | 2.98 |
| 2026 | 6.21 | 3.14 |
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 year
More from this analysisDoes Sell in May and Go Away Work?
S&P 500 tracker: May to October vs November to April, season by season
ranking 21×3
→
SPY distributions by ex-dividend month: inside the May to October window vs outside it
ranking 19×3
→
Average S&P 500 tracker return by calendar month, May 2005 through April 2026
table 12×5
→
The seasonal gap by era: average half-year returns and the spread between them
table 3×6
→
See all 2,173 queries →