Skip to content

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.

    Quickstart

  • The app


    racinglines.bet: Markets, Trade, History and Lab. Click Try the demo to look around, or sign up for the fantasy league alpha.

    Web app

  • The CLI


    One command, task first: racinglines data | model | strategy | markets | book | live | db ..., with --demo on any of them.

    CLI reference

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

    MCP server

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

  1. 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:

git config core.hooksPath scripts/hooks   # skip once with: git push --no-verify

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.