Unusual Whales API - Seasonality endpoints

Layer mapping: L1 partial. Seasonality is a calendar-context feature, not a signal. Knowing “May has historically been -0.4% on SPY” doesn’t change today’s setup - but combined with regime gates it adds prior probability framing.

Four endpoints: market-level, per-ticker monthly, this-month best performers, and year-month historical performance.

1. Base contract

PropertyValue
Base URLhttps://api.unusualwhales.com
AuthAuthorization: Bearer <token> header
Response envelope{ "data": [...] }
Status codes200, 422, 500

2. Endpoint matrix

#PathPurposeLayer
1GET /api/seasonality/marketMarket-level seasonality (likely SPY + major indices)L1 partial
2GET /api/seasonality/{ticker}/monthlyPer-ticker monthly seasonalityL1 partial (SPY)
3GET /api/seasonality/month-performersBest historical performers in current monthL2
4GET /api/seasonality/{ticker}/year-monthYear-by-year monthly performance for one tickerL1 partial (SPY)

3. GET /api/seasonality/market - Market-level

Market-level monthly seasonality (likely SPY + QQQ + sector ETFs).

No documented parameters.

Response per record:

FieldTypeDescription
tickerstringIndex / ETF symbol
monthint1-12
yearsintSample size (how many years averaged)
avg_changedecimal (string)Average monthly % change
median_changedecimal (string)Median monthly % change
max_changedecimal (string)Best historical month
min_changedecimal (string)Worst historical month
positive_closesintCount of positive monthly closes
positive_months_percdecimal (string)Pct of months that closed positive

MK3 use (L1). Session-start one-shot pull. Cache for the trading day. Derived features:

  • spy_current_month_avg_change (from this endpoint, current month)
  • spy_current_month_positive_pct (historical hit rate)
  • current_month_seasonality_regime = positive / negative / neutral based on positive_months_perc and median_change

Used as a prior, not a gate. “May has 55% positive close rate” shifts the Setup Hunter’s confidence threshold but does not veto trades.

4. GET /api/seasonality/{ticker}/monthly - Per-ticker

Same record shape, filtered to one ticker.

Path parameter: ticker (e.g. SPY).

Use (L1). For SPY hunter specifically, this is more granular than the market endpoint (which returns multiple tickers). Returns all 12 months for one ticker.

5. GET /api/seasonality/{ticker}/year-month - Year-by-year

Historical year-month grid for one ticker (each row = one specific year + month combination, not aggregated).

Path parameter: ticker.

Response per record (inferred): year, month, change_pct, open, close, high, low.

Use (L1). Drill into the variance behind the average. The market endpoint says “May average -0.4%” but year-month shows whether that’s “consistently -0.4% every year” vs “wild range from -10% to +8% averaging -0.4%“. The latter is much less informative.

Derived feature: spy_current_month_change_stddev - high variance means seasonality is weak signal even if the average is suggestive.

6. GET /api/seasonality/month-performers - L2

Best historical performers in the current month across the universe.

Query parameters (inferred): month, min_marketcap, limit.

Response per record: ticker, avg_change for the month, hit rate, sample size.

Use (L2). Pick stocks that historically outperform in the current month for swing-trade strategy. Not in MK3 scope.

7. MK3 use summary

EndpointCadenceCache TTL
/seasonality/marketSession start, once1 day
/seasonality/SPY/monthlySession start, once1 day
/seasonality/SPY/year-monthSession start, once1 day
/seasonality/month-performersNot wiredL2 only

Three endpoint calls at session start, three derived features:

  • spy_seasonality_score (combining hit rate + average)
  • spy_seasonality_strength (1 - stddev / |mean|)
  • spy_month_regime (positive/negative/neutral discrete bucket)

Total cost: 3 HTTP calls, ~1 KB response data, used as a confidence- modulating prior across the trading day.

8. Nautilus integration shape

Single one-shot Actor at session start: UWSeasonalityActor. Calls all three SPY-relevant endpoints, computes derived features, publishes once to the bus as a UWSeasonalityContext snapshot. Strategies subscribe and read at decision time, never re-poll.

9. Known gaps

  • /seasonality/market scope unclear. Returns multiple tickers but the docs don’t enumerate which. First fetch should catalog (SPY, QQQ, IWM, sector ETFs? individual stocks?).
  • /year-month response shape inferred. First fetch should confirm.
  • /month-performers filter parameters inferred. L2-only; defer.
  • No intraday or weekly seasonality. Monthly is the finest granularity. Day-of-week, time-of-day, and turn-of-month effects live elsewhere (probably need a separate research session cross-referencing the 1Y UW bundle).

10. Source URLs

  • https://api.unusualwhales.com/docs/operations/PublicApi.SeasonalityController.market_seasonality
  • https://api.unusualwhales.com/docs/operations/PublicApi.SeasonalityController.monthly
  • https://api.unusualwhales.com/docs/operations/PublicApi.SeasonalityController.year_month
  • https://api.unusualwhales.com/docs/operations/PublicApi.SeasonalityController.month_performers

cortana-north-star uw-api-tide uw-api-market 2026-05-15-mk3-setup-hunter-architecture