Seasonal strategy

Santa Claus Rally

Captures year-end strength across the last 5 trading days of December and the first 2 of January on SPY.

Production
Seasonal
SPY
Backtest

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).

66.7%
Win rate
2.72
Profit factor
+0.80%
Avg / trade
5.1%
Max drawdown
CAGR
not published
Exposure
not published
33
Total trades
7d
Avg holding

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.

DriverMechanism
Light holiday volumeThin participation lets modest buying move the tape.
Year-end inflowsBonuses, 401(k) contributions and fund flows arrive around the turn of the year.
Tax-loss selling doneThe December tax-loss selling pressure has largely cleared by the window.
Window dressing / optimismManagers 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 DecembernthLastTradingDay(decYear, 12, 6) — the session just before the seven-day window opens.

Exit

The 2nd trading day of JanuarynthTradingDay(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/rewardRiskRatio are null. 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.

ComponentMaxAwarded
seasonalWindow6060 while the window is Active (today inside it), else 0.
windowProximity4040 × (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.
DimensionIdeal
MarketBroad US equities (SPY), calm-to-positive year-end with normal holiday participation.
TraderPassive, rules-driven — takes the window every year as a small seasonal overlay.
TimeframeOne ~7-session window each turn of the year.
Avoid whenAn active bear market or a macro shock lands in the window; or when costs swamp the ~0.8% edge.
  • **basis enum gap** — the historicalPattern.basis is "published"|"derived"; there is no "empirical" value, so the empirical path is labelled "derived" with the real provenance in note.
  • Static snapshot — baked as of 2026; the live /api/backtest always 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
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_rally

This 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
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.*