Repository navigation
3. Sports Season Router
The SportsSeasonRouter is the automated market routing engine responsible for directing the Kalshi trading bot to the highest-liquidity sports markets throughout the calendar year.
Rather than remaining pinned to a single league or suffering orderbook starvation during off-seasons or midweek schedule lulls, the router dynamically cascades through active, in-season sports suites (Game Lines and Player Props) and verifies live two-sided orderbook depth before posting quotes.
The router supports the four dominant liquidity drivers on Kalshi: NFL, NCAAF (College Football), NBA, and MLB.
Low-liquidity leagues and off-market sports are permanently excluded from automated routing to prevent the bot from becoming trapped in wide-spread or one-sided orderbooks.
| League | Category | Specific Series Tickers | Description |
|---|---|---|---|
| NFL | Game Lines |
KXNFLGAMEKXNFLSPREADKXNFLTOTAL
|
• Moneyline (Game Winner) • Point Spread • Game Total Over/Under |
| Player Props |
KXNFLTDKXNFLPASSYDSKXNFLRSHYDSKXNFLRECYDSKXNFLPASSTDS
|
• Anytime Touchdown Scorer • Quarterback Passing Yards • Running Back Rushing Yards • Receiver Receiving Yards • Passing Touchdowns Over/Under |
|
| NCAAF | Game Lines |
KXNCAAFGAMEKXNCAAFSPREADKXNCAAFTOTAL
|
• Moneyline (Game Winner) • Point Spread • Game Total Over/Under |
| NBA | Game Lines |
KXNBAGAMEKXNBASPREADKXNBATOTAL
|
• Moneyline (Game Winner) • Point Spread • Game Total Over/Under |
| Player Props |
KXNBAPTSKXNBAREBKXNBAASTKXNBA3PTKXNBAPRA
|
• Player Points Over/Under • Player Rebounds Over/Under • Player Assists Over/Under • Player Made 3-Pointers • Points + Rebounds + Assists Combo |
|
| MLB | Game Lines |
KXMLBGAMEKXMLBSPREADKXMLBTOTAL
|
• Moneyline (Game Winner) • Run Line (+/- 1.5 runs) • Total Runs Over/Under |
| Player Props |
KXMLBKSKXMLBHRKXMLBHITKXMLBTB
|
• Pitcher Strikeouts Over/Under • Player to Hit a Home Run • Player Total Hits • Player Total Bases |
The router inspects the current US Eastern Time (ET) date and month to determine active league priorities:
| Month | Active Sports Phase | Priority 1 | Priority 2 | Priority 3 | Priority 4 | Behavior if Dormant |
|---|---|---|---|---|---|---|
| Jan | NFL Playoffs / CFP National Championship / NBA Midseason |
NFL Complete Suite: • Lines: KXNFLGAME, KXNFLSPREAD, KXNFLTOTAL• Props: KXNFLTD, KXNFLPASSYDS, KXNFLRSHYDS, KXNFLRECYDS, KXNFLPASSTDS
|
NCAAF Game Lines: • Lines: KXNCAAFGAME, KXNCAAFSPREAD, KXNCAAFTOTAL
|
NBA Complete Suite: • Lines: KXNBAGAME, KXNBASPREAD, KXNBATOTAL• Props: KXNBAPTS, KXNBAREB, KXNBAAST, KXNBA3PT, KXNBAPRA
|
— | Idle & Retry Discovery |
| Feb | Super Bowl / NBA Post-All-Star |
NFL Super Bowl Suite: • Lines: KXNFLGAME, KXNFLSPREAD, KXNFLTOTAL• Props: KXNFLTD, KXNFLPASSYDS, KXNFLRSHYDS, KXNFLRECYDS, KXNFLPASSTDS
|
NBA Complete Suite: • Lines: KXNBAGAME, KXNBASPREAD, KXNBATOTAL• Props: KXNBAPTS, KXNBAREB, KXNBAAST, KXNBA3PT, KXNBAPRA
|
— | — | Idle & Retry Discovery |
| Mar | NBA Stretch Run / MLB Opening |
NBA Complete Suite: • Lines: KXNBAGAME, KXNBASPREAD, KXNBATOTAL• Props: KXNBAPTS, KXNBAREB, KXNBAAST, KXNBA3PT, KXNBAPRA
|
MLB Opening Suite: • Lines: KXMLBGAME, KXMLBSPREAD, KXMLBTOTAL• Props: KXMLBKS, KXMLBHR, KXMLBHIT, KXMLBTB
|
— | — | Idle & Retry Discovery |
| Apr | NBA Playoffs / MLB Opening Month |
NBA Playoffs Suite: • Lines: KXNBAGAME, KXNBASPREAD, KXNBATOTAL• Props: KXNBAPTS, KXNBAREB, KXNBAAST, KXNBA3PT, KXNBAPRA
|
MLB Complete Suite: • Lines: KXMLBGAME, KXMLBSPREAD, KXMLBTOTAL• Props: KXMLBKS, KXMLBHR, KXMLBHIT, KXMLBTB
|
— | — | Idle & Retry Discovery |
| May | NBA Conf. Finals / MLB Reg Season |
NBA Complete Suite: • Lines: KXNBAGAME, KXNBASPREAD, KXNBATOTAL• Props: KXNBAPTS, KXNBAREB, KXNBAAST, KXNBA3PT, KXNBAPRA
|
MLB Complete Suite: • Lines: KXMLBGAME, KXMLBSPREAD, KXMLBTOTAL• Props: KXMLBKS, KXMLBHR, KXMLBHIT, KXMLBTB
|
— | — | Idle & Retry Discovery |
| Jun | NBA Finals / MLB Reg Season |
NBA Finals Suite: • Lines: KXNBAGAME, KXNBASPREAD, KXNBATOTAL• Props: KXNBAPTS, KXNBAREB, KXNBAAST, KXNBA3PT, KXNBAPRA
|
MLB Complete Suite: • Lines: KXMLBGAME, KXMLBSPREAD, KXMLBTOTAL• Props: KXMLBKS, KXMLBHR, KXMLBHIT, KXMLBTB
|
— | — | Idle & Retry Discovery |
| Jul | Summer Lull: MLB Midseason / All-Star |
MLB Complete Suite: • Lines: KXMLBGAME, KXMLBSPREAD, KXMLBTOTAL• Props: KXMLBKS, KXMLBHR, KXMLBHIT, KXMLBTB
|
— | — | — | Idle & Retry Discovery |
| Aug | MLB Pennant Races (NFL/NCAAF Preseason Excluded) |
MLB Complete Suite: • Lines: KXMLBGAME, KXMLBSPREAD, KXMLBTOTAL• Props: KXMLBKS, KXMLBHR, KXMLBHIT, KXMLBTB
|
— | — | — | Idle & Retry Discovery |
| Sep | NFL & College Football Kickoff / MLB Final Month |
NFL Complete Suite: • Lines: KXNFLGAME, KXNFLSPREAD, KXNFLTOTAL• Props: KXNFLTD, KXNFLPASSYDS, KXNFLRSHYDS, KXNFLRECYDS, KXNFLPASSTDS
|
NCAAF Game Lines: • Lines: KXNCAAFGAME, KXNCAAFSPREAD, KXNCAAFTOTAL
|
MLB Complete Suite: • Lines: KXMLBGAME, KXMLBSPREAD, KXMLBTOTAL• Props: KXMLBKS, KXMLBHR, KXMLBHIT, KXMLBTB
|
— | Idle & Retry Discovery |
| Oct | Quadruple Overlap: NFL, NCAAF, NBA Tip-Off, MLB World Series |
NFL Complete Suite: • Lines: KXNFLGAME, KXNFLSPREAD, KXNFLTOTAL• Props: KXNFLTD, KXNFLPASSYDS, KXNFLRSHYDS, KXNFLRECYDS, KXNFLPASSTDS
|
NCAAF Game Lines: • Lines: KXNCAAFGAME, KXNCAAFSPREAD, KXNCAAFTOTAL
|
NBA Complete Suite: • Lines: KXNBAGAME, KXNBASPREAD, KXNBATOTAL• Props: KXNBAPTS, KXNBAREB, KXNBAAST, KXNBA3PT, KXNBAPRA
|
MLB Postseason Suite: • Lines: KXMLBGAME, KXMLBSPREAD, KXMLBTOTAL• Props: KXMLBKS, KXMLBHR, KXMLBHIT, KXMLBTB
|
Idle & Retry Discovery |
| Nov | NFL Midseason / NCAAF Rivalry Month / NBA Reg Season |
NFL Complete Suite: • Lines: KXNFLGAME, KXNFLSPREAD, KXNFLTOTAL• Props: KXNFLTD, KXNFLPASSYDS, KXNFLRSHYDS, KXNFLRECYDS, KXNFLPASSTDS
|
NCAAF Game Lines: • Lines: KXNCAAFGAME, KXNCAAFSPREAD, KXNCAAFTOTAL
|
NBA Complete Suite: • Lines: KXNBAGAME, KXNBASPREAD, KXNBATOTAL• Props: KXNBAPTS, KXNBAREB, KXNBAAST, KXNBA3PT, KXNBAPRA
|
— | Idle & Retry Discovery |
| Dec | NFL Playoff Push / NCAAF Bowl Season & CFP / NBA Christmas |
NFL Complete Suite: • Lines: KXNFLGAME, KXNFLSPREAD, KXNFLTOTAL• Props: KXNFLTD, KXNFLPASSYDS, KXNFLRSHYDS, KXNFLRECYDS, KXNFLPASSTDS
|
NCAAF Game Lines: • Lines: KXNCAAFGAME, KXNCAAFSPREAD, KXNCAAFTOTAL
|
NBA Complete Suite: • Lines: KXNBAGAME, KXNBASPREAD, KXNBATOTAL• Props: KXNBAPTS, KXNBAREB, KXNBAAST, KXNBA3PT, KXNBAPRA
|
— | Idle & Retry Discovery |
During football season (September through January), both the NFL and College Football (NCAAF) are active. To maximize liquidity capture based on real-world scheduling, the router evaluates calendar priority using US Eastern Time (America/New_York):
-
Friday & Saturday (College Football Primetime):
- College Football is the dominant national event across Friday night games and the full Saturday slate.
- NCAAF is elevated to Priority 1, ahead of NFL, NBA, and MLB.
-
October Example:
NCAAF$\rightarrow$ NFL$\rightarrow$ NBA$\rightarrow$ MLB.
-
Sunday, Monday, Thursday (NFL Game Days):
- The NFL holds its primary slate on Sunday (early, afternoon, and Sunday Night Football), Monday Night Football, and Thursday Night Football.
- NFL retains Priority 1, ahead of NCAAF, NBA, and MLB.
-
October Example:
NFL$\rightarrow$ NCAAF$\rightarrow$ NBA$\rightarrow$ MLB.
-
Tuesday & Wednesday (Midweek Lulls):
- Standard seasonal priority applies; when no active NFL/NCAAF games are live, the waterfall seamlessly cascades to midweek NBA or MLB postseason games.
flowchart TD
Start([Market Discovery Request]) --> FetchMarkets[Fetch Eligible Markets Once via REST<br>fetch_eligible_markets]
FetchMarkets --> RouteCheck{User Specified<br>Target Preference?}
RouteCheck -- "Exact Ticker (e.g. KXNFLGAME-...)" --> ExactCheck{Active Exact<br>Match Found?}
ExactCheck -- "Yes & Has Quotes" --> SelectedMarket([Selected Market Locked In])
ExactCheck -- "Excluded / Settled / Starved" --> DetectLeague[Route to League Suite e.g. KXNFL->NFL<br>or Seasonal Fallback]
RouteCheck -- "Specific League (e.g. NBA)" --> ManualOverride[Set Target League: e.g. NBA]
RouteCheck -- "Default / SPORTS / None" --> Router[SportsSeasonRouter.get_in_season_leagues]
DetectLeague --> Matrix[/Lookup Priority Sequence/]
ManualOverride --> Matrix
Router --> CheckDate[Check Current Eastern Date & Month]
CheckDate --> Matrix
Matrix --> NextTier{Next Tier in<br>Waterfall?}
NextTier -- Yes --> FilterSeries[Filter In-Memory Markets for Series<br>Tier 1A Moneylines -> 1B Spreads/Totals -> Tier 2 Props]
FilterSeries --> HasCandidates{Active Candidates<br>Found?}
HasCandidates -- No --> NextTier
HasCandidates -- Yes --> ExcludeIneligible[Exclude Synthetic KXMVE & Excluded Tickers]
ExcludeIneligible --> HorizonRank[Rank Candidates by Liquidity<br>+ Expiration Horizon Multiplier]
HorizonRank --> PreFlight[Pre-Flight Orderbook Verification<br>Probe up to 2 Candidates per Series<br>10 Probes Total Budget]
PreFlight --> HasTwoSidedQuotes{Two-Sided Quotes<br>Confirmed?}
HasTwoSidedQuotes -- Yes --> SelectedMarket
HasTwoSidedQuotes -- No --> NextTier
NextTier -- No (Exhausted / Budget Depleted) --> IdleRetry([Idle & Retry Discovery Cycle<br>No Unwanted Capital Allocation])
To prevent selecting multi-year distant futures with misleading historical volume (such as 2-year season props), contracts are scored with dynamic expiration multipliers:
-
$\le 7$ Days (Upcoming this week):$3.0\times$ -
$\le 14$ Days (Next week):$2.0\times$ -
$\le 30$ Days (This month):$1.5\times$ -
$\le 90$ Days (This season):$1.0\times$ -
$\le 365$ Days (Longer term):$0.5\times$ -
$> 365$ Days (Distant futures):$0.05\times$ (heavily discounted)
Contracts matching active league prefixes (KXNFL, KXNBA, KXMLB, KXNCAAF) receive a flat +500,000 boost in the liquidity scoring formula.
Before committing the market maker to any contract, the bot performs a lightweight REST query to /trade-api/v2/markets/{ticker}/orderbook to verify live liquidity:
-
Validation Criteria: Both
len(yes_bids) > 0andlen(no_bids) > 0. -
Probe Budgeting & Rate Limit Protection:
-
Per-Series Limit: The router probes at most 2 candidates per series (
DEFAULT_MAX_PROBES_PER_SERIES = 2). -
Total Discovery Budget: A shared ceiling of 10 total probes (
DEFAULT_MAX_TOTAL_PROBES = 10) applies across all tiers in a single discovery cycle. If the probe quota is exhausted, discovery halts cleanly to prevent REST rate-limit penalties.
-
Per-Series Limit: The router probes at most 2 candidates per series (
- Failover: If a candidate is dormant or has one-sided quotes, it is bypassed in favor of the next ranked candidate in the series (up to 2 probes). If both fail, the router cascades to the next tier/series in the seasonal hierarchy.
When operators launch the bot targeting a specific contract ticker (e.g. TARGET_TICKER="KXNFLGAME-26SEP17DETBUF"), the bot locks onto that contract on startup. If that market reaches expiration/settlement or encounters prolonged orderbook starvation, the bot's auto-rotation mechanism calls discovery with that ticker added to exclude_tickers.
To prevent the bot from becoming permanently stalled:
-
League-Specific Cascade: If the target ticker begins with or references a supported league prefix (
KXNFL$\rightarrow$ NFL,KXNCAAF$\rightarrow$ NCAAF,KXNBA$\rightarrow$ NBA,KXMLB$\rightarrow$ MLB), discovery routes directly to that league's full suite (Tier 1A moneylines, Tier 1B game lines, and Tier 2 props) to locate an active replacement within the same sport. -
Seasonal Fallback: If the excluded target does not map to a recognized league prefix, discovery falls back to
SportsSeasonRouter.get_in_season_leagues(), ensuring the bot rotates to the highest-liquidity seasonal market rather than idling indefinitely.
To maximize capital velocity and prevent the bot from selecting multi-month or season-long futures (such as season win totals or KXNFLENDSTREAK contracts that resolve months later), automated discovery enforces a strict rolling expiration ceiling:
-
Default Window (
MAX_EXPIRATION_DAYS = 8): Configurable via theMAX_EXPIRATION_DAYSenvironment variable. Defaults to 8 days to span the full weekly NFL/CFB broadcast slate (Thursday through Monday) plus Kalshi's post-game settlement buffer. -
Early Filtering Across Tiers: Any contract with
close_time > now + MAX_EXPIRATION_DAYSis strictly excluded from candidate pools across Tier 1A (Moneylines), Tier 1B (Spreads/Totals), Tier 2 (Props), and Tier 3 (General League Catch-All). -
Targeted Series Query Fallback: If global
/eventspagination omits upcoming game lines (e.g. due to hundreds of unrelated political/financial event listings), discovery executes targeted series queries (series_ticker="KXNFLGAME",series_ticker="KXNCAAFGAME",series_ticker="KXMLBGAME") with the weekly horizon bound, ensuring game lines are located reliably. -
Exact Ticker Bypass: Operators explicitly injecting an exact contract (via
TARGET_TICKER="<exact_ticker>") bypass the horizon filter, preserving the flexibility to quote any specific market if explicitly desired.