racinglines¶
Fair prices and market-making tools for race-sport prediction markets, priced strictly as of any moment and tested on real market tapes.
Tools for an edge in race-sport prediction markets. racinglines turns official timing into win, podium, head-to-head and championship odds, priced strictly as of any moment and tested on real market tapes, and gives makers and takers the tools to find and size an edge inside the existing markets. Two sports mark the ends of the range we build for:
- Formula 1, the big end: priced against Polymarket, with live paper trading from October 2026;
- UCI downhill mountain biking, the small end: modelled and forecast, waiting for an exchange to list it.
New sports qualify when their audience and expected market liquidity sit between the two. NASCAR Cup and MotoGP are the first: results, market links on Kalshi, Polymarket and OG.com, and a simple result-only model in replay, with no edge yet that held up in a second season. Where every sport stands on every exchange: Sports and exchanges.
Start here¶
-
Quickstart
Install, build a synthetic demo store and run the whole pipeline in about 5 minutes. Every command is shown with the output it really printed.
-
The app
racinglines.bet: Markets, Trade, History and Lab. Click Try the demo to look around, or sign up for the fantasy league alpha.
-
The CLI
One command, task first:
racinglines data | model | strategy | markets | book | live | db ..., with--demoon any of them. -
MCP: ask Claude
The same data and simulations as typed tools, local over stdio or hosted at
mcp.racinglines.bet, for Claude Code, Claude Desktop or the CLI.
At a glance¶
| ๐๏ธ 129 F1 races backtested | 2021 to Azerbaijan 2026. Each race is priced before practice, before qualifying and after qualifying. After qualifying, top-10 Brier is 0.149 against 0.163 for a grid-only guess; the best variant also beats it on win and podium. |
| ๐น Every Polymarket F1 race weekend, replayed | 38 weekends (2025 and 2026) on the real prices and trade tape. The default maker made +$751 on $8,969 filled in 2026. |
| โ๏ธ 1,161 strategy combinations searched | A 4-hour cloud search found two setups that held up in both seasons: A (a taker, +$1,232 in 2026 / +$1,237 in 2025) and C (a maker, +$653 / +$835, the best Sharpe of any combination). |
| ๐ก Live paper trading | A and C run on every F1 weekend Polymarket lists, through 2027, stage by stage, with heat ratings, alerts and paper positions, through the same code as the backtest (checked trade for trade). Polymarket lists F1 race markets again: production's database holds them for every 2026 round from Italy (6 Sep) to Brazil (8 Nov), checked 2026-10-14. |
| ๐ด Live events | The Whistler downhill final (27 Sep 2026) followed live from UCI timing: rank probabilities after every update, a maker re-quoting every rider, 1,000 simulated private-book takers and a hype-picking demo taker, P&L by venue. Live events and private books are admin-only while the fantasy alpha runs (Alpha layout). |
| ๐ Three exchanges, eight sports | Polymarket, Kalshi and OG.com (OG.com read-only, from one schema file). F1 is the only sport with a real model and a backtest that held in a held-out season (on Polymarket). NASCAR on Kalshi: 2026 +$4.2k to +$5.5k in the taker replay but โ$242 to โ$390 in 2025 in every setting, on spiky last-trade prices, so not robust. MotoGP: race win only, no held-out season. Both show to every signed-in user (MotoGP again since 2026-10-14). Road cycling is priced by the same engine, for admins only. IndyCar, Le Mans and SailGP: recorded tapes, no model. Of the 3 ร 3 grid (F1, NASCAR, MotoGP ร Polymarket, Kalshi, OG.com), 8 cells hold data; only MotoGP on OG.com is empty (OG.com doesn't list it). Status matrix. |
| ๐ฎ Fantasy league alpha, open | Every signed-in account gets F$1,000 of fantasy money: trade F1 markets by hand on the recorded order books, or follow one of five strategy styles, and climb the leaderboard. No real money, nothing reaches an exchange. Alpha layout, Fantasy trading. |
| ๐ต 43 downhill World Cup rounds | 2021โ2026, walk-forward. Error on who makes the Final is 38% lower than a uniform guess (0.127 vs 0.204); the actual winner got 7.1% on average, against ~1%. |
| โ Checks in seconds | racinglines check runs 21 checks (code, every data source, database) in ~10 s; the regression suite runs 1,552 tests (2026-10-14) on pinned public fixtures and golden outputs. |
The goal isn't to out-predict the market everywhere: on race-winner odds Polymarket is about as sharp as the model (sharper after qualifying, and in 2025 at every stage). The tools act only where the gap is large, and quote where it's safe. Nothing is traded with real money until paper trading has validated the backtests. The pages below have the details.
Try it¶
-
Open racinglines.bet and click Try the demo (it signs in as the demo maker), or sign up for the fantasy league alpha. What is this? on the same page opens Racinglines 101, a plain-language introduction. Signed in, the app has four tabs:
- Markets: the prediction markets now, with our fair price against each venue for every sport you can see (F1, NASCAR, MotoGP);
- Trade: fantasy trading in F$ on the recorded order books, one immediate-or-cancel order at a time (F1 only);
- History: your F$, every trade and order, your strategy's trades and the leaderboard;
- Lab: follow a strategy style and size it, its track record and positions, and the backtests, Edge Finder and replays.
The demo accounts can look but not trade (sign up to trade). Their track records are replays of real weekends, and nothing a visitor changes in a demo session is kept. The quickstart replay plays the command line in the browser, no sign-in needed. 2. Run it locally, then check the setup (about 10 seconds, nothing downloaded):
python3.14 -m venv .venv && source .venv/bin/activate # Python 3.11+
pip install -r requirements.txt && pip install -e . # dependencies + the `racinglines` command
racinglines check # code, data endpoints, database (~10 s)
The demo (Quickstart, each command with its real output): the real commands on a synthetic Mario
Kart season, a separate database built on first use (needs Postgres: docker compose up -d):
racinglines model backtest kart --demo # every past race priced as of before it, scored
racinglines model forecast kart --demo --save # the rest of the season and the championships
racinglines live run kart/demo-2026-09 --demo --simulate --no-fetch # a live private book, 100 simulated takers
Then the full pipeline:
docker compose up -d # PostgreSQL on localhost:5433 (or a conda Postgres: see Database)
racinglines db init # tables + reference data
racinglines data fetch f1 && racinglines data ingest f1 # F1 sessions (FastF1) -> database
racinglines model forecast f1 --save # live F1 prices: remaining races + championships
racinglines markets sync # Polymarket's F1 markets
racinglines data ingest mtb_dh # downhill event files -> database
racinglines model forecast mtb_dh --db --save # downhill season forecast
racinglines strategy profiles f1 --assign-demo # strategy profiles A and C for the demo accounts
racinglines strategy signals f1 # live paper signals (outside a race weekend: a no-op)
ADMIN_PASSWORD=... racinglines web # the app on http://127.0.0.1:8000
What it does¶
official timing โโ> PostgreSQL โโ> as-of model โโ> simulated weekends โโ> fair prices โโ> markets
(FastF1, (one multi- (only sessions & seasons (win, podium, (Polymarket;
ChronoRace) sport schema) ended before (thousands of runs) h2h, pole, paper trading,
the cutoff) titles) replays, Lab)
- Collects official timing into one multi-sport PostgreSQL schema:
- F1 via FastF1: every practice, qualifying, sprint and race session since 2020;
- downhill split timing from ChronoRace, 2021โ2026.
Exchange history (prices, trades, order books) goes to a Parquet archive.
- Models each sport:
- F1: a sector-aware car model shared by both team drivers, driver
offsets, a practice-pace prior, and a grid/overtaking finishing model, with
challenger variants behind switches;
- Downhill: a log-time model of each rider's pace, consistency and
crash/DNF rate.
- Simulates race weekends and seasons thousands of times: win, podium,
top 10, pole, head-to-head and team markets, plus championships.
- Prices strictly as of a moment: only sessions that have ended before the
cutoff are used, and a leakage guard enforces it. Backtests, diagnostics, the
live forecast and the signal engine all call the same function.
- Tests strategies on real market data: maker replays, taker strategies that
re-trade after every session, and a season-long championship strategy, all on
Polymarket's recorded prices and trades; settings searches run locally or in
the cloud.
- Paper trades live: strategy profiles (A, a taker; C, a maker) produce
signals at every stage of a race weekend, with heat ratings for takers,
alerts, paper fills and positions. No real orders are placed.
- Web app (racinglines.bet), laid out for the fantasy league alpha:
- Markets: our fair price against each venue for each sport's next races;
- Trade and History: fantasy trading in F$ on the recorded books, every trade, and the leaderboard;
- Lab: follow a strategy style, its track record and positions, and the Edge Finder, backtests, scenario
forecasts, diagnostics and strategy replays with your own settings.
- Reaches the hosted server from the command line: --remote runs the book commands and Lab jobs on
racinglines.bet, racinglines remote calls any hosted tool, and racinglines data pull SPORT copies one sport's
shared data into your own database (MCP server).
Remote access is in testing (#aintcare mode): the review of venue and data-feed terms is pending, so what the
server returns is for testing only, and every remote command prints that warning.
Results¶
| Question | Answer | Details |
|---|---|---|
| How accurate is the F1 model? | Beats uniform everywhere and a grid-only guess on top 10; the best variant also beats it on win and podium after qualifying. | F1 evaluation |
| How does it compare with Polymarket? | Close, which is the point: in 2026 better mid-weekend on race winners, worse after qualifying; in 2025 the market is sharper at every stage. The edge comes from the few large gaps. | F1 evaluation โ Against Polymarket |
| Can it make money on Polymarket? | In backtests, yes: the default maker +$751 over 2026; profiles A and C made money in both 2025 and 2026. Live paper trading is the test. | Market making, Paper trading |
| Which model, traded which way? | A: the update taker on gridq+pretrain+reset, 10-point edges (5 on head-to-head), no pre-weekend stage. C: the conservative maker on gbm, 5-point filter, 25-share quotes. |
Market making โ Cloud settings search |
| What does F1 look like now? | The next race's favourites and the championship odds. | F1 forecast |
| How accurate is the downhill model? | Better than uniform on podium and make-Final in every season; win odds too flat. | Downhill evaluation |
| Who wins the 2026 downhill title? | Downhill forecast | |
| What about NASCAR, MotoGP, Kalshi and OG.com? | Data and a simple result-only model for NASCAR and MotoGP; no strategy outside F1 on Polymarket has passed a held-out season. OG.com is readable and replayable, not tradable. | Sports and exchanges |
Explore, one layer at a time¶
Each layer builds on the one before, so start at the top and stop when you have what you need. F1 and downhill each have a model, an evaluation and a forecast page, and F1 also has market pages. NASCAR, MotoGP and the tape-only sports are summarised on one status page.
| Layer | Page | What's there |
|---|---|---|
| 0. Status | Sports and exchanges | Every sport ร exchange: data, model, backtest and its caveats, live or paper, and the gaps |
| 1. Data | Data | Sources, what was downloaded, the on-disk layout, and what's in git |
| Parser | Downhill results formats and the tidy schema | |
| Database | The multi-sport schema, ingest, stored runs, the snapshot, and what stays in Postgres vs Parquet | |
| Exchanges as schemas | OG.com read from one TOML file: sync, tape, fair-price indicator, buy-all check | |
| 2. Formula 1 | F1 model | Car and driver pace, practice prior, finishing model, as-of pricing |
| F1 evaluation | 129-race backtest, model variants, against Polymarket | |
| F1 forecast | The next race and the championships | |
| Market making | Maker replay, season sweeps, the model ร strategy matrix, the cloud settings search, season strategy | |
| Paper trading | Profiles A and C, the signal engine, heat, alerts, the demo accounts | |
| 3. Downhill | Downhill model | Log-time rider model, weekend formats, season simulation |
| Downhill evaluation | 43-round walk-forward, per season and per event | |
| Downhill forecast | The live 2026 title projection | |
| 4. Use it | Quickstart | The whole pipeline on a synthetic demo store, every command with its real output |
| Web app | Pages and routes, roles, demo accounts and sessions, the Lab, the private book, Polymarket orders | |
| CLI reference | Every group and command, its -h output and options |
|
| MCP server | The data and simulations as typed tools for Claude Code, Claude Desktop or the CLI | |
| Live events | A race followed live: the live model, the maker's quotes, the private book's crowd, replay logs | |
| 5. Operate | VM deploy | How racinglines.bet is run: deploys, timers, staging, backups |
| Cloud sweeps | Running settings searches on a cloud machine | |
| Testing | Quick check, regression suite, fixtures, golden outputs | |
| 6. Roadmap | Roadmap ยท F1 live test ยท F1 roadmap | What's next, in priority order; this week's F1 live test; the phased F1 plan with its ground rules |
| Project history ยท F1 reference | How it got here, and the model and market-making ideas behind the F1 plan |
Collaborators and beta testers¶
We're looking for beta testers and collaborators! Try the app at racinglines.bet, and if you'd like to help, test, or just say hi, drop us a line at [email protected]. We'd love to hear from you. The contributor guide says how to get set up.
Building these docs¶
The top-level README.md is the short version. Parts of it are generated
from sections of these pages (see Docs & README). The command outputs on these
pages are captured by scripts/docs/capture_examples.py on the kart demo store (scripts/docs/examples.toml
lists them) and embedded as snippets, never typed by hand.
pip install -r requirements-docs.txt
mkdocs serve # live preview at http://127.0.0.1:8000
mkdocs build # static HTML in site/
python scripts/build_readme.py # refresh README.md from sections tagged in docs/
A pre-push hook blocks a push unless the docs build with --strict, the README
matches the docs, and no data outside the allow-list is tracked. Enable it once
per clone:
On very new Pythons (e.g. 3.14), watchdog may have no prebuilt package and fail
to build. It's only needed for mkdocs serve's live reload. Either use
Python โค3.13, or install with pip install --no-deps mkdocs mkdocs-get-deps
plus mkdocs's other dependencies, then run mkdocs build and open
site/index.html.
Repo layout¶
| Path | |
|---|---|
racinglines/cli/ |
The racinglines command, task first: data, model, strategy, markets, book, live, db, web, mcp, remote, check and more (CLI reference) |
racinglines/sources/ |
Data sources: fastf1/ (fetch, ingest), chronorace/ (download, parse, ingest), http.py (paced, retried requests for every source) |
racinglines/models/ |
The one engine, model_global.py (every modelled sport's pricing model, its inputs declared in sports/<code>.toml [model]), and its input layers in inputs/: laps.py, laps_pricing.py, practice.py, grid.py (F1: car/driver pace, sectors, practice prior, race and season pricing), run_times/ (downhill: log-time model, weekend and season simulation), results.py (finishing positions); variants.py, props.py, evaluate.py beside them |
racinglines/markets/ |
Exchanges and books: Polymarket sync/trade/links, Kalshi client/sync/trade, the Parquet store, venues, the private_book, new-market and signal alerts, and strategies/ (maker replay, weekend taker, season) |
racinglines/pipelines/ |
Multi-stage runs: weekend_sweep, sweep_settings, search (settings searches), season_strategy, season_checkpoints, profiles, signals (live paper trading), story and demo_history (the demo accounts) |
racinglines/db/ |
Database: models, reads, queries, shared ingest helpers, the snapshot, registry of sports and venues |
racinglines/web/ |
The web app (racinglines web): Markets, Trade, History, Lab and admin under the alpha layout (layout.py; the older pages are archived behind it); demo sessions (demo.py); old-URL redirects (legacy.py) |
racinglines/testing/ |
Synthetic data and the checks behind racinglines check |
sports/*.toml, racinglines/sports.py |
Sport schemas: what differs between sports (sessions, points, categories, venues, markets), read by the code |
racinglines/paths.py |
Where data lives (data/raw, data/archive, data/runs, data/cache) |
migrations/, alembic.ini |
Alembic schema migrations |
tests/, scripts/fetch_test_fixtures.py |
Regression suite on fixtures built from public sources, plus golden outputs (see Testing) |
scripts/ |
build_readme.py, signals_parity.py, cloud/ (prepare and start a cloud run), launchd agents for the recorder and the signal engine, hooks/pre-push |
sweeps/ |
Settings-search queues (TOML) |
docker-compose.yml |
Local PostgreSQL 17 (port 5433) |
pyproject.toml, requirements.txt, requirements-docs.txt |
Package (pip install -e . for the racinglines command); pinned dependencies (pipeline / docs site) |
data/ |
Downloads, the market archive, run outputs and caches; only an allow-listed minimal set is in git (see Data) |
docs/, mkdocs.yml |
Documentation site (MkDocs) |
pitch.html |
The pitch deck, served at /pitch (screenshots in racinglines/web/static/pitch/) |
Internal book¶
Day-in-the-life (DITL) reports, the golden rules for building and deploying taker strategies, house rules, the
project's history and the full report index live in an internal book at /docs/internal/ (admins only). Access can be
requested via [email protected].
Downhill points are placeholders
Downhill championship points use approximate tables, not the official UCI scale. Every downhill number measured in points (expected points, standings, champion odds) is approximate until points validation is done. Win, podium, top-10 and make-Final probabilities don't depend on points.