Santa Claus Rally
Captures year-end strength across the last 5 trading days of December and the first 2 of January on SPY.
Performance
Real internal-backtest statistics from the registry — Internal backtest · SPY daily bars (Yahoo Finance) · 33 windows · 1993–2026 (Stock Trader's Almanac cites ~79% / ~+1.3% for the S&P 500 since 1950).
CAGR and exposure are not published for the library yet — we show “—” rather than invent them. Max drawdown, best year and worst year are undefined for the pooled Momentum universe backtest. Win rate is a share of trades, average return is per trade, and holding period is in trading days.
Historical pattern
Santa Claus Rally — average cumulative return across the held window
Trading sessions from entry (0 = buy at the 6th-last Dec close; last 5 of Dec + first 2 of Jan follow) · Average cumulative return (%). Empirical average path computed across all 33 completed backtest windows on real SPY daily closes — measured from history, NOT illustrative and NOT externally published. Anchored at the entry (the 6th-last December session); each point averages the windows that reached it (offsets 0–6 all 33; the Jan +2 exit 32 — one window was holiday-shortened). Labelled basis:"derived" only because the frozen v1 enum offers no "empirical" value.
The "Santa Claus Rally" is a seven-trading-day window straddling the New Year that has historically shown a positive bias. This strategy buys SPY at the close of the trading day just before the window opens (the 6th-to-last trading day of December) and sells at the close of its final day (the 2nd trading day of January), holding cash the rest of the year.
- Buy at the close of the 6th-to-last trading day of December.
- Sell at the close of the 2nd trading day of January.
- One trade per year; ~7 trading sessions held.
Best for
Calm, positive year-ends with normal holiday participation — light volume, seasonal inflows and an optimistic mood.
Avoid when
Years dominated by macro shocks, rate scares or an active bear market, when news overwhelms the light-volume seasonal drift. A missing Santa Claus Rally is itself watched as a bearish tell.
Market behaviour exploited
Seasonal, flow-driven year-end strength — lighter holiday trading, year-end bonus/401(k) inflows, tax-loss selling having washed out earlier in December, and institutional window-dressing.
| Driver | Mechanism |
|---|---|
| Light holiday volume | Thin participation lets modest buying move the tape. |
| Year-end inflows | Bonuses, 401(k) contributions and fund flows arrive around the turn of the year. |
| Tax-loss selling done | The December tax-loss selling pressure has largely cleared by the window. |
| Window dressing / optimism | Managers tidy books into year-end; a generally positive holiday mood prevails. |
A tendency, not a guarantee — the effect is well known and can fail in any given year.
One pure core (santaClausSignalFromBars) backs the live state and the backtest adapter, using the shared trading calendar so both agree on the anchors.
Entry
The 6th-to-last trading day of December —
nthLastTradingDay(decYear, 12, 6)— the session just before the seven-day window opens.
Exit
The 2nd trading day of January —
nthTradingDay(decYear + 1, 1, 2)— the last day of the window.
Detected by boundary-crossing on actual bar dates (weekends/holidays skipped), so each fires exactly once per year and the trade holds across the New Year.
Position management
- Date-defined, not price-defined: no stop or target.
entryPrice/stopLoss/firstTarget/riskPercent/rewardRiskRatioarenull. Risk control is the short, fixed ~7-session hold and being in cash otherwise.
Deterministic, from the shared seasonalConfidence model. confidenceScore is a setup-quality measure (0–100), not a probability of profit.
| Component | Max | Awarded |
|---|---|---|
seasonalWindow | 60 | 60 while the window is Active (today inside it), else 0. |
windowProximity | 40 | 40 × (10 − daysUntilEntry)/10 over the 10 days before entry, clamped to [0,40]. |
100 inside the window; ramps 0 → 60+ as it approaches; 0 far away. Bands: <70 Weak · 70–79 Good · 80–89 Strong · 90–100 Exceptional.
The API returns ["Santa Claus Rally window is active"] while Active, else [].
- It is on/after the 6th-last trading day of December.
- Position entered at that session's close in SPY.
- No stop or target — the exit is the date.
- Exit at the close of the 2nd trading day of January.
- Flat (in cash) outside the window.
- Structural, seasonal edge with a long, corroborated history (SPY backtest + Almanac since 1950).
- High hit-rate (66.7%), PF 2.72, shallow 5.1% max drawdown.
- Objective and mechanical — unambiguous calendar dates, no discretion.
- Minimal exposure — ~7 sessions/year, in cash otherwise.
- Small edge (~0.8%/trade), well known and possibly decaying.
- Tiny annual sample — one trade/year; a few years dominate.
- Macro-override risk — a risk-off tape can erase it (worst year −4.60%).
- No hard stop — a bad window is taken in full (bounded by the short hold).
- Close-to-close — no commissions/slippage modelled.
| Dimension | Ideal |
|---|---|
| Market | Broad US equities (SPY), calm-to-positive year-end with normal holiday participation. |
| Trader | Passive, rules-driven — takes the window every year as a small seasonal overlay. |
| Timeframe | One ~7-session window each turn of the year. |
| Avoid when | An active bear market or a macro shock lands in the window; or when costs swamp the ~0.8% edge. |
- **
basisenum gap** — thehistoricalPattern.basisis"published"|"derived"; there is no"empirical"value, so the empirical path is labelled"derived"with the real provenance innote. - Static snapshot — baked as of 2026; the live
/api/backtestalways recomputes. - Single-vendor, close-to-close — Yahoo prices; SPY history from 1993.
API examples
Real responses from the live endpoints for this strategy.
Live strategy
GET /api/strategies?id=santa_claus_rally{
"strategies": [
{
"id": "santa_claus_rally",
"name": "Santa Claus Rally",
"category": "Seasonality",
"asset": "SPY",
"description": "WHAT IT IS: The Santa Claus Rally is a well-known seasonal tendency…",
"historical": {
"yearsTested": 33,
"winRate": 0.6667,
"averageReturn": 0.8,
"bestYear": 7.76,
"worstYear": -4.6,
"maxDrawdown": 5.1,
"averageHoldingPeriod": 7,
"profitFactor": 2.72,
"totalTrades": 33,
"source": "Internal backtest · SPY daily bars (Yahoo Finance) · 33 windows · 1993–2026 (Stock Trader's Almanac cites ~79% / ~+1.3% for the S&P 500 since 1950)"
},
"historicalPattern": {
"title": "Santa Claus Rally — average cumulative return across the held window",
"xLabel": "Trading sessions from entry (0 = buy at the 6th-last Dec close; last 5 of Dec + first 2 of Jan follow)",
"yLabel": "Average cumulative return (%)",
"basis": "derived",
"source": "Internal backtest — 33 completed SPY windows (Yahoo Finance daily closes), 1993–2026",
"note": "Empirical average path computed across all 33 completed backtest windows on real SPY daily closes…",
"series": [
{ "day": 0, "label": "Entry (Dec −6)", "cumulativeReturn": 0.0 },
{ "day": 1, "label": "Dec −5", "cumulativeReturn": 0.18 },
{ "day": 2, "label": "Dec −4", "cumulativeReturn": 0.54 },
{ "day": 3, "label": "Dec −3", "cumulativeReturn": 0.55 },
{ "day": 4, "label": "Dec −2", "cumulativeReturn": 0.56 },
{ "day": 5, "label": "Dec −1", "cumulativeReturn": 0.28 },
{ "day": 6, "label": "Jan +1", "cumulativeReturn": 0.63 },
{ "day": 7, "label": "Exit (Jan +2)", "cumulativeReturn": 0.83 }
]
},
"status": "Upcoming",
"entryDate": "2026-12-22",
"exitDate": "2027-01-04",
"daysUntilEntry": 140,
"entryPrice": null, "stopLoss": null, "firstTarget": null, "riskPercent": null, "rewardRiskRatio": null,
"confidenceScore": 0,
"confidenceBreakdown": { "seasonalWindow": 0, "windowProximity": 0 },
"explanation": "The Santa Claus Rally window opens 2026-12-22 (140 days away) and exits 2027-01-04…",
"checklist": [],
"score": 70, "recommended": true, "weight": "medium"
}
]
}Scanner
GET /api/scan?strategy=santa_claus_rallyThis is a market-wide calendar strategy, not a per-symbol screen, so /api/scan?strategy=santa_claus_rally returns { "supported": false } with a clear message.
Backtest
GET /api/backtest?strategy=santa_claus_rally{
"strategy": "santa_claus_rally",
"symbol": "SPY",
"range": { "requestedFrom": null, "requestedTo": null, "testedFrom": "1993-01-29", "testedTo": "2026-08-04", "barsTested": 8435 },
"metrics": {
"totalTrades": 33, "winningTrades": 22, "losingTrades": 11,
"winRate": 0.6667, "averageReturn": 0.008, "medianReturn": 0.008,
"bestTrade": 0.0776, "worstTrade": -0.046, "averageHoldingPeriod": 6.97,
"profitFactor": 2.7231, "totalReturn": 0.2894, "maxDrawdown": 0.051
},
"sampleTrades": [
{ "entryDate": "2025-12-23", "exitDate": "2026-01-05", "entryPrice": 585.10, "exitPrice": 584.90, "return": -0.0003, "holdingDays": 7 }
],
"openTradeEntryDate": null
}References
- Yale Hirsch / Jeffrey Hirsch, Stock Trader's Almanac — coined "Santa Claus Rally"; cites ~79% positive, ~+1.3% for the S&P 500 since 1950.
- Backtest data: SPY daily OHLCV via Yahoo Finance, 1993–2026 (
lib/market-data/prices.ts).
*Past behaviour does not ensure future results. confidenceScore measures setup quality, not the probability of profit.*