Championship markets¶
Season-long markets for the soft-launch sports (F1, NASCAR Cup, MotoGP) on Polymarket, Kalshi and OG.com, what the
syncs call them, and which of them a model prices. Taken from the code, the schemas and the captured listings in
tests/fixtures/market (2026-09-29). Live listings were not checked from the cloud. Last reviewed 2026-09-30.
Model-priced means a model run writes a fair value that db.reads.model_prob or a command reads. Quote only
means the market is synced and recorded, but no model prices it.
| Sport | Exchange | Market | Listing | Kind (where) | Priced |
|---|---|---|---|---|---|
| F1 | Kalshi | Drivers' champion | KXF1 |
champion (kalshi/sync.py) |
Model: pricing.forecast standings, on the board |
| F1 | Kalshi | Constructors' champion | KXF1CONSTRUCTORS |
constructors_champion |
Model: forecast constructors |
| F1 | Polymarket | Drivers' / Constructors' champion | "F1 Drivers' Champion", "F1 Constructors' Champion" | champion / constructors_champion (polymarket/sync.py) |
Model |
| F1 | Polymarket | Season wins ("win N+ Grands Prix") | question wording | season_wins_ge |
Model: forecast extra.wins_ge |
| F1 | Polymarket | Standings head-to-head | question wording | standings_h2h |
Model: forecast extra.ahead_of |
| F1 | OG.com | Drivers' / Constructors' champion | F1-00001-2026, F1-00002-2026 (20 contracts) |
champion / constructors_champion (exchanges/og.toml) |
Model (venue shown with RACINGLINES_OG_VENUE=1) |
| NASCAR | Kalshi | Cup champion | KXNASCARCUPSERIES, KXNASCARCUPCHAMP |
params.kind = champion, link unmodeled (sources/nascar/links.py) |
Model, offline: racinglines model season nascar --quotes (off by default, read-only) |
| NASCAR | Polymarket | Cup champion | nascar-cup-series-2026-champion-… |
champion from the wording |
Model, offline: the same |
| NASCAR | OG.com | Cup champion | NSCAR-00002-2026 (17 contracts) |
champion; og.toml modeled = false |
Model, offline: the same |
| NASCAR | Kalshi | Regular-season champion | KXNASCARCUPSEASON |
regular_season_champion |
Quote only (settled for 2026: the regular season ended 29 Aug) |
| NASCAR | Kalshi | In-Season Challenge | KXNASCARCHALLENGE |
in_season_challenge |
Quote only (a bracket tournament, not the points table) |
| NASCAR | Kalshi | O'Reilly (Xfinity) / Truck champion | KXNASCARAUTOPARTSSERIES, KXNASCARTRUCKSERIES |
champion, nascar_series xfinity / trucks |
Quote only (only Cup results are ingested) |
| MotoGP | Kalshi | World champion | KXMOTOGP (22 markets) |
none: unmodeled (sources/motogp/links.py knows only KXMOTOGPRACE) |
Model, offline: motogp season-replay reads it as champion in memory |
| MotoGP | Kalshi | Teams' championship | KXMOTOGPTEAMS (11 markets) |
none: unmodeled |
Quote only |
| MotoGP | Polymarket | World champion (25 outcomes) | tag motogp |
none: unmodeled |
Model, offline: the same (from the wording) |
| MotoGP | OG.com | none listed |
How far a model price goes. None of these champion prices has a backtest that held up. The F1 season forecast lost money on Polymarket's 2026 championship markets at every checkpoint and in every model variant (−$566 to −$797 over 33 markets, Market making): early in a new-regulations season the market knew more than the model. The NASCAR season sim (#93) is not calibrated: it has never been scored on a settled season, it ignores track types and form drift, and its first Mac run had Larson at 94.6% against 40–55% on the market (before its second revision). The replays that would test these prices on Kalshi and OG.com (F1: #95; NASCAR and MotoGP: #96) are merged on main (off by default, below) but not yet run on the VM as of 2026-09-30. Read every "Model" cell above as a fair value to compare with the quote, not as a validated edge. The full sport × exchange status: Sports and exchanges.
No exchange lists a NASCAR standings top 3, a standings head-to-head or season wins, although the season simulation
could price them (markets.kinds.season_fair). No NASCAR manufacturers' or owners' championship was found either.
What pricing MotoGP's champion would take¶
The MotoGP race model (MotoGPRaceChallenger) prices one race at a time, so it could feed a season simulation the way
the NASCAR model does. What is missing:
- Sprint points.
MotoGPRace.loadreads the Sunday race only, and sprint classifications are not ingested yet (sources/motogp/ingest.py). The sprint pays 12-9-7-6-5-4-3-2-1 every weekend, so the season total is wrong without it. - The remaining schedule. The MotoGP ingest files completed events only. The events endpoint that
fetch.pyalready reads has the dates. - Today's standings. Summed race and sprint points, or the world-standing classification in
tests/fixtures/market/motogp_standings_2026_motogp.json, which nothing ingests yet. - Classifiers.
KXMOTOGPshould map tochampion(andKXMOTOGPTEAMSto a team kind), and Polymarket's wording tochampion. That changes stored link params, so it needs the owner's go andlink --applywith a backup. - A points format. A
ChaseFormat-like table with no playoff (25-20-16-13-11-10-9-8-7-6-5-4-3-2-1 for the race).
Steps 1-3 need a probe from the Mac first (standing rule), so none of this is built.
Update (2026-09-30): a replay-only version is built (racinglines strategy season-replay motogp, off by default with
RACINGLINES_SEASON_REPLAY=1, read-only). It covers the steps above without changing any stored link.
- models/motogp_season.py supplies the points format (5).
- The remaining schedule is the stored events plus the fetched events.json (2).
- The standings are summed from the stored Grand Prix and sprint points (3). With no sprint results stored, both sides
are Grand Prix only and the report prints SPRINT POINTS MISSING (1).
- The classifier runs in memory only: KXMOTOGP, or a listing naming the championship, is read as champion, and the
rider comes from the name resolver (4). Nothing is written.
Championship replays (backtests)¶
racinglines strategy season-replay nascar and racinglines strategy season-replay motogp (pipelines/season_replay.py) trade the F1
championship sleeve's default strategy (markets/strategies/season.py) against each exchange's recorded champion
prices.
- Decisions: one at 12:00 UTC the day after each points race.
- Fairs: an as-of season forecast from only the results before the decision. For NASCAR this is
models/nascar_season.py summed from race results, because the points feed is today's only.
- Costs: Kalshi's taker fee, OG.com's flat fee, or Polymarket's half-spread, each plus slippage.
Both commands are read-only and off by default (RACINGLINES_SEASON_REPLAY=1). They write only CSVs under
data/runs/season-replay/<sport>-<venue>-<year>/ (decisions.csv, trades.csv, positions.csv, equity.csv,
summary.json); --venue all (the default) runs every exchange the sport lists, one report each
(CLI).
The F1 replay takes --venue kalshi|og too: racinglines strategy season-strategy f1 --venue kalshi|og replays the default
championship strategy on that exchange's stored tape (no fetch). Kalshi is costed at its taker fee; OG.com at its flat
$0.02 per contract, with no volume floor and prices read as its replay venue reads them (an empty book's 0.50 dropped).
Polymarket stays the default and its output is unchanged. --save with another venue stores kind season_venue_replay,
so no page reads it as Polymarket's; --paper stays Polymarket or Kalshi.
These are first backtest cells, not validated strategies. Both season forecasts simulate races independently from the form at the decision, and NASCAR's was more favourite-heavy than every exchange on 2026-09-30.