santa_windows
Answered against 22 years of US equities and 12 years of US options data and published with the query that produced it. This result is stored as of 2026-09-17, from santa-claus-rally.
| year | measured_from | measured_to | santa_window_pct | calendar_december_pct |
|---|---|---|---|---|
| 2003 | Dec 23 | Jan 5 | 2.47 | 4.54 |
| 2004 | Dec 23 | Jan 4 | -1.61 | 2.53 |
| 2005 | Dec 22 | Jan 4 | 0.48 | -0.72 |
| 2006 | Dec 21 | Jan 4 | 0.04 | 0.78 |
| 2007 | Dec 21 | Jan 3 | -2.21 | -1.65 |
| 2008 | Dec 23 | Jan 5 | 7.76 | 0.17 |
| 2009 | Dec 23 | Jan 5 | 1.5 | 1.36 |
| 2010 | Dec 23 | Jan 4 | 1.1 | 6.12 |
| 2011 | Dec 22 | Jan 4 | 1.94 | 0.41 |
| 2012 | Dec 21 | Jan 3 | 2.06 | 0.18 |
| 2013 | Dec 23 | Jan 3 | 0.19 | 2.04 |
| 2014 | Dec 23 | Jan 5 | -2.9 | -0.8 |
| 2015 | Dec 23 | Jan 5 | -2.26 | -2.31 |
| 2016 | Dec 22 | Jan 4 | 0.53 | 1.43 |
| 2017 | Dec 21 | Jan 3 | 1.08 | 0.7 |
| 2018 | Dec 21 | Jan 3 | 1.46 | -9.33 |
| 2019 | Dec 23 | Jan 3 | 0.37 | 2.4 |
| 2020 | Dec 23 | Jan 5 | 1.02 | 3.26 |
| 2021 | Dec 23 | Jan 4 | 1.48 | 4.26 |
| 2022 | Dec 22 | Jan 4 | 0.8 | -6.19 |
| 2023 | Dec 21 | Jan 3 | -0.83 | 4.14 |
| 2024 | Dec 23 | Jan 3 | -0.46 | -2.73 |
| 2025 | Dec 23 | Jan 5 | -0.03 | -0.22 |
- Rows × columns
- 23 × 5
- Computed
- Completeness
- No missing values
- Source
- US exchange, SIP and OPRA market data
- Licence
- Strasmore terms · free, no signup
What each column holds
| Column | Type | Range | Notes |
|---|---|---|---|
year |
number | 2,003 to 2,025 | |
measured_from |
text | 3 distinct values (Dec 21, Dec 22, Dec 23) | |
measured_to |
text | 3 distinct values (Jan 3, Jan 4, Jan 5) | |
santa_window_pct |
number | -2.9 to 7.76 | percent |
calendar_december_pct |
number | -9.33 to 6.12 | percent |
Computed from Strasmore's warehouse of US exchange, SIP and OPRA market data. Equity prices are delayed; options greeks and implied volatility are end-of-day. This result is stored, not recomputed on load — it is exactly the numbers that were returned on , and the query below is what returned them.
the exact SQL behind every number
WITH
spy_days AS
(
SELECT
date,
toYear(date) AS y,
toMonth(date) AS m,
argMax(toFloat64(close), _ingest_time) AS close
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'SPY'
AND toMonth(date) IN (11, 12, 1)
GROUP BY date
),
ranked AS
(
SELECT
date,
y,
m,
close,
row_number() OVER (PARTITION BY y, m ORDER BY date DESC) AS sessions_from_end,
row_number() OVER (PARTITION BY y, m ORDER BY date ASC) AS sessions_from_start
FROM spy_days
)
SELECT
toUInt16(if(m = 1, y - 1, y)) AS year,
concat(formatDateTime(anyIf(date, m = 12 AND sessions_from_end = 6), '%b '),
toString(toDayOfMonth(anyIf(date, m = 12 AND sessions_from_end = 6)))) AS measured_from,
concat(formatDateTime(anyIf(date, m = 1 AND sessions_from_start = 2), '%b '),
toString(toDayOfMonth(anyIf(date, m = 1 AND sessions_from_start = 2)))) AS measured_to,
round((anyIf(close, m = 1 AND sessions_from_start = 2)
/ anyIf(close, m = 12 AND sessions_from_end = 6) - 1) * 100, 2) AS santa_window_pct,
round((anyIf(close, m = 12 AND sessions_from_end = 1)
/ anyIf(close, m = 11 AND sessions_from_end = 1) - 1) * 100, 2) AS calendar_december_pct
FROM ranked
GROUP BY year
HAVING countIf(m = 11 AND sessions_from_end = 1) = 1
AND countIf(m = 12 AND sessions_from_end = 6) = 1
AND countIf(m = 1 AND sessions_from_start = 2) = 1
ORDER BY year
Run your own version of this
The same 22 years of US equities and 12 years of options data are queryable in SQL or plain English. A free account runs 100 queries a day and takes no card.