# racinglines > racinglines turns official race timing into win, podium, head-to-head and championship odds for race-sport prediction markets (Formula 1 on Polymarket and Kalshi, UCI downhill mountain biking, NASCAR Cup and MotoGP), priced strictly as of any moment and tested on real market tapes. These docs cover the data pipelines, the pricing models and their evaluation, market making and paper trading, the sportsbook slip schema, the web app and MCP server, the CLI (with a synthetic kart demo pack that runs offline), and how the production VM is run. --- # 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](coverage.md). ## Start here
- :material-rocket-launch: **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. [:octicons-arrow-right-24: Quickstart](quickstart.md) - :material-web: **The app** --- [racinglines.bet](https://racinglines.bet): Markets, Trade, History and Lab. Click **Try the demo** to look around, or sign up for the fantasy league alpha. [:octicons-arrow-right-24: Web app](webapp.md) - :material-console: **The CLI** --- One command, task first: `racinglines data | model | strategy | markets | book | live | db ...`, with `--demo` on any of them. [:octicons-arrow-right-24: CLI reference](cli.md) - :material-robot: **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. [:octicons-arrow-right-24: MCP server](mcp.md)
## 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](alpha-layout.md)). | | ๐Ÿ **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](coverage.md#the-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](alpha-layout.md), [Fantasy trading](fantasy-trading.md). | | ๐Ÿšต **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](https://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](https://racinglines.bet/racinglines101), 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](https://racinglines.bet/docs/quickstart/term) 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](quickstart.md), 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](https://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](mcp.md#more-commands-on-the-hosted-server-remote-racinglines-remote-data-pull)). 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](f1-evaluation.md) | | 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](f1-evaluation.md#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](market-making.md), [Paper trading](paper-trading.md) | | 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](market-making.md) | | What does F1 look like now? | The next race's favourites and the championship odds. | [F1 forecast](f1-forecast.md) | | How accurate is the downhill model? | Better than uniform on podium and make-Final in every season; win odds too flat. | [Downhill evaluation](evaluation.md) | | Who wins the 2026 downhill title? | [Downhill forecast](forecast.md) | | | 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](coverage.md) | ## 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](coverage.md) | Every sport ร— exchange: data, model, backtest and its caveats, live or paper, and the gaps | | 1. **Data** | [Data](data.md) | Sources, what was downloaded, the on-disk layout, and what's in git | | | [Parser](parser.md) | Downhill results formats and the tidy schema | | | [Database](database.md) | The multi-sport schema, ingest, stored runs, the snapshot, and what stays in Postgres vs Parquet | | | [Exchanges as schemas](exchanges.md) | OG.com read from one TOML file: sync, tape, fair-price indicator, buy-all check | | 2. **Formula 1** | [F1 model](f1.md) | Car and driver pace, practice prior, finishing model, as-of pricing | | | [F1 evaluation](f1-evaluation.md) | 129-race backtest, model variants, against Polymarket | | | [F1 forecast](f1-forecast.md) | The next race and the championships | | | [Market making](market-making.md) | Maker replay, season sweeps, the model ร— strategy matrix, the cloud settings search, season strategy | | | [Paper trading](paper-trading.md) | Profiles A and C, the signal engine, heat, alerts, the demo accounts | | 3. **Downhill** | [Downhill model](model.md) | Log-time rider model, weekend formats, season simulation | | | [Downhill evaluation](evaluation.md) | 43-round walk-forward, per season and per event | | | [Downhill forecast](forecast.md) | The live 2026 title projection | | 4. **Use it** | [Quickstart](quickstart.md) | The whole pipeline on a synthetic demo store, every command with its real output | | | [Web app](webapp.md) | Pages and routes, roles, demo accounts and sessions, the Lab, the private book, Polymarket orders | | | [CLI reference](cli.md) | Every group and command, its `-h` output and options | | | [MCP server](mcp.md) | The data and simulations as typed tools for Claude Code, Claude Desktop or the CLI | | | [Live events](live-events.md) | A race followed live: the live model, the maker's quotes, the private book's crowd, replay logs | | 5. **Operate** | [VM deploy](vm-deploy.md) | How racinglines.bet is run: deploys, timers, staging, backups | | | [Cloud sweeps](cloud-sweep.md) | Running settings searches on a cloud machine | | | [Testing](testing.md) | Quick check, regression suite, fixtures, golden outputs | | 6. **Roadmap** | [Roadmap](todo.md) ยท [F1 live test](f1-live-roadmap.md) ยท [F1 roadmap](f1-roadmap.md) | What's next, in priority order; this week's F1 live test; the phased F1 plan with its ground rules | | | [Project history](history.md) ยท [F1 reference](f1-reference.md) | 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](https://racinglines.bet), and if you'd like to help, test, or just say hi, drop us a line at [hello@racinglines.bet](mailto:hello@racinglines.bet?subject=racinglines%20beta%20tester%20%2F%20collaborator). We'd love to hear from you. The [contributor guide](contributing.md) 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](cli.md#scriptsbuild_readmepy)). 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](cli.md)) | | `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/.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](testing.md)) | | `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](data.md)) | | `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 hello@racinglines.bet. !!! warning "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](todo.md#points-validation) is done. Win, podium, top-10 and make-Final probabilities don't depend on points. --- # Quickstart > The whole pipeline on synthetic data, with the real commands: install, build a demo store, backtest, forecast, run a live private book and price a sportsbook's lines. About 5 minutes once Postgres is up. Every command below is a normal `racinglines` command with `--demo` added. `--demo` switches the data source to a **demo store** (a separate database and data folder filled from a [data pack](demo.md)) and changes nothing else. The default pack, `kart`, is a synthetic Formula 1 world with a Mario Kart grid: every pace, result and price is invented; play money, nothing is traded anywhere. !!! note "What you need" Python 3.11 or newer and a PostgreSQL 16+ server. No API key, no account and no network access are needed for the demo. The hosted way in needs only Python and a racinglines.bet account with MCP access (in testing). !!! tip "Installing from PyPI?" `pip install "racinglines[db]"` is the shortest way in: the [package README](https://pypi.org/project/racinglines/) walks through the same demo from the installed package, with the database in one `docker run`. The package is F1, the downhill sim, the kart demo and the web app; `[db]` runs every command, `pip install "racinglines[mcp]"` adds the MCP server and the hosted way in (`--remote`, `racinglines remote`, `data pull`), and `pip install "racinglines[web]"` adds the web app. The NASCAR, MotoGP, road cycling and weather commands on this page are not in it. Prefer to watch first? The same commands, recorded, play in the browser at [racinglines.bet/docs/quickstart/term](https://racinglines.bet/docs/quickstart/term), no sign-in needed. ## Which way in? === "Local (demo store), recommended" Everything runs on your machine. The demo store is built on first use (about a minute) and every command works on it. ### Setup (5 min) #### Step 1: Install ```bash # LOCAL (Mac), or any machine with Python 3.11+ and Docker python3 -m venv ~/rl && source ~/rl/bin/activate pip install "racinglines[db]" # or, in a clone of racinglines-public: pip install -e ".[web]" ``` #### Step 2: Start Postgres ```bash # LOCAL (Mac): PostgreSQL 17 on localhost:5433, data in the Docker volume racinglines-pgdata docker run -d --name racinglines-db -p 5433:5432 -e POSTGRES_USER=racinglines -e POSTGRES_PASSWORD=racinglines \ -e POSTGRES_DB=racinglines -v racinglines-pgdata:/var/lib/postgresql/data postgres:17 ``` In a clone of the full development repository, `docker compose up -d` starts the same server (`docker-compose.yml`). Without Docker, any Postgres 16+ works: point `DATABASE_URL` at it ([Database](database.md#setup)). The demo database is created next to the configured one (`racinglines_demo_kart` on the same server), so the user in the URL needs the right to create databases (the container's user has it). #### Step 3: Check the install `racinglines check` runs the pipelines on synthetic data, probes every data source and checks the database (about 10 seconds). `--offline` skips the endpoint probes; `--no-db` skips the database. === "Command" ```bash title="Command" racinglines check --offline ``` === "Output" ```text title="Output" code (synthetic data) โœ“ f1 code load + measurements 0.3s 6 events, 7,485 laps, 360 practice rows โœ“ f1 code as-of leakage guard 0.0s sessions only usable after they end โœ“ f1 code training history 0.6s 120 training rows โœ“ f1 code race pricing 1.2s favourite Driver 01 36% โœ“ f1 code backtest 0.6s 6 race x mode rows, mean win Brier 0.032 โœ“ f1 code season forecast 0.3s leader Driver 01 71% โœ“ markets code maker replay 0.0s 172 fills, P&L +72.56 โœ“ markets code weekend taker 0.0s 46 trades, P&L +300.15 โœ“ markets code season strategy 0.2s 39 trades, P&L -93.55 โœ“ mtb_dh code parse results tables 0.1s 1920 rows, 60 riders, rounds ['final', 'practice', 'qual1'] โœ“ mtb_dh code season model 0.2s sigma 0.0096, 60 riders โœ“ mtb_dh code season forecast 0.2s leader 69% โœ“ mtb_dh code backtest 0.2s 1 held-out round(s) scored database โœ“ database Postgres 0.2s localhost:5433/racinglines, schema up to date 14/14 checks passed ``` #### Step 4: Choose where the data comes from The first command that needs a database, when none is configured (no `DATABASE_URL`, no `db` or `source` in `~/.config/racinglines/cli.toml`), asks once and saves the answer as `source` in that file. Answer `1`: ```text racinglines needs a database, and none is configured (no DATABASE_URL, no `db` or `source` in ~/.config/racinglines/cli.toml). 1) local: the Postgres of docker-compose.yml on localhost:5433; start it with one command, `docker compose up -d` (then every command works; add --demo for the synthetic demo store, docs/quickstart.md) 2) remote: sign in to racinglines.bet (the browser opens on first use) and run `racinglines book map|price|settle` on the hosted server, like `racinglines remote ...` and `--remote` on a Lab-job command (in testing); other commands still need a local database Choose 1 or 2 [1]: ``` With no terminal to ask on (a script, CI), it prints the same two options and exits with code 2: set `DATABASE_URL`, or run `racinglines book config source local` (or `remote`). The same command changes the answer later. One resolver makes this choice and the `--demo` one (`racinglines/cli/source.py`). Now [run the quickstart](#run-the-quickstart-the-kart-pack). === "Hosted (racinglines.bet, in testing)" !!! warning "#aintcare mode" racinglines.bet remote access is in testing (#aintcare mode). A review of venue and data-feed terms is pending, so data served here is for testing only. Every command that connects to the hosted server prints this warning on stderr. !!! info "Sign up on racinglines.bet first" Every `--remote` command needs a racinglines.bet token, which comes from your sign-in on the site: [sign up](https://racinglines.bet/signup) before Step 2. The hosted demo store (`--demo --remote`) may let you try a few calls without a token first, then asks you to sign up. The local tab needs no account. From PyPI, these commands need the MCP extra: `pip install "racinglines[mcp]"`. Nothing to install but the CLI itself, no Postgres: `--remote` sends the commands the hosted server runs to racinglines.bet, and `--demo --remote` sends them to the pack's **hosted demo store** (`racinglines mcp --http --demo` on the VM, over its own database built from the pack: synthetic data only, never production's). The outputs below are not shown because these commands need the hosted server, which the docs build cannot reach. ### Setup (2 min) #### Step 1: Install the CLI ```bash # LOCAL (Mac), or any machine with Python 3.11+: no Postgres needed git clone https://github.com/racinglines/racinglines.git && cd racinglines # the development repository python3 -m venv .venv && source .venv/bin/activate pip install -r requirements.txt && pip install -e . ``` #### Step 2: Sign in The first `--remote` command opens the browser to sign in with your racinglines.bet account (one with MCP access: Pro or admin, [MCP: Hosted](mcp.md#hosted-the-vm)) and waits for **Allow**. The login is kept in `~/.config/racinglines/mcp-login.json` and refreshed on its own; `racinglines book logout` forgets it. On a machine with no browser, an `rl_` token from Settings > Connect Claude (MCP) in `RACINGLINES_MCP_TOKEN` skips the sign-in. ```bash # LOCAL (Mac): the pack's book, priced on the hosted demo store (the browser opens once) racinglines book price --demo --remote ``` #### Step 3: Run the model as a hosted job On the hosted store the model commands run as the server's Lab jobs (`run_job`, followed with `get_job`), the log printed as it arrives, and the run is saved there. They take the job's options only (`--races`, `--sims`, `--track`, `--half-life`, `--scenario`; `--half-life-days`, `--junior-weight` for `mtb_dh`). ```bash # LOCAL (Mac) racinglines model backtest kart --demo --remote --races 10 # the backtest as a hosted job racinglines model forecast kart --demo --remote # a forecast scenario on the hosted demo store ``` `db stats`, `live run` and `live report` need a local store. The pack names its server (`[remote] mcp_url` in `pack.toml`; `RACINGLINES_DEMO_MCP_URL` overrides it); it answers once the owner has built it on the VM (`scripts/vm/demo_store.sh`, [Demo data packs](demo.md#the-hosted-demo-store)). With `source = "remote"` saved in `~/.config/racinglines/cli.toml`, `--demo` alone goes to the hosted store too. #### Step 4: Pull real data into your own database (optional) The same sign-in reaches more of the hosted server ([MCP: More commands on the hosted server](mcp.md#more-commands-on-the-hosted-server-remote-racinglines-remote-data-pull)): `--remote` on any command that has a Lab job, `racinglines remote tools | call | job`, and `racinglines data pull SPORT`, which copies one sport's shared data (race data, model runs, exchange prices, trades and books; never accounts or positions) into a local database: ```bash # LOCAL (Mac), or any machine with Postgres: a fresh local database, then F1's data from racinglines.bet racinglines db init racinglines data pull f1 racinglines data pull f1 --since last # later: a top-up ``` ## Run the quickstart (the kart pack) The steps come from the pack's manifest (`racinglines/demo/packs/kart/pack.toml`, `[[quickstart]]`, rendered by `python3 scripts/build_quickstart.py`), and every **Output** tab is what the command printed on the pack, captured by `scripts/docs/capture_examples.py` (never typed by hand). The [browser replay](https://racinglines.bet/docs/quickstart/term) records the same list. Run them in order. ### Step 1: ๐Ÿ“ฆ Install racinglines In a virtualenv with Python 3.11+: the package with its database extra (from a clone of racinglines-public, `pip install -e ".[web]"`). ```bash # LOCAL (Mac), or any machine with Postgres pip install "racinglines[db]" ``` ### Step 2: ๐Ÿ„ Build and look at the demo store The first --demo command builds the store (a few minutes, with a progress bar): the database, the synthetic files, the real ingest and the exchange links. Later commands reuse it. === "Command" ```bash title="Command" racinglines db stats --demo ``` === "Output" ```text title="Output" demo: building the kart pack's store (no database): database racinglines_demo_kart, folder /home/user/racinglines-public/data/demo/kart. Synthetic data, made once (a few minutes). ๐Ÿ”ง demo store 0/7 creating the database ๐Ÿ”ง demo store 1/7 schema and reference data (alembic upgrade head, seed) ๐Ÿ”ง demo store 2/7 the pack's data files ๐Ÿ”ง demo store generating: 2024 R01 Mario Kart Stadium ๐Ÿ”ง demo store generating: 2025 R01 Mario Kart Stadium ๐Ÿ”ง demo store generating: 2026 R01 Mario Kart Stadium ๐Ÿ”ง demo store generating: files written ๐Ÿ”ง demo store generating: exchange odds 2026-09 ๐Ÿ”ง demo store generating: exchange odds 2026-10 ๐Ÿ”ง demo store generating: exchange odds 2026-11 ๐Ÿ”ง demo store 3/7 racinglines data ingest f1 --years 2024-2026 ๐Ÿ”ง demo store 4/7 racinglines model forecast f1 --save --sims 2000 ๐Ÿ”ง demo store 5/7 racinglines data pm-links-import f1 ๐Ÿ”ง demo store 6/7 racinglines data pm-links-import f1 --exchange kalshi ๐Ÿ”ง demo store 7/7 ready demo: the kart store is ready (f1 data; `racinglines db stats --demo kart`) Let's-a go! ๐Ÿ„ โ•ญโ”€ ๐Ÿ“ฆ database racinglines_demo_kart โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ ๐Ÿ“… calendar ๐Ÿ results ๐Ÿ”ฎ model โ”‚ โ”‚ sports 8 athletes 20 model runs 1 โ”‚ โ”‚ leagues 8 athlete identifiers 20 race predictions 60 โ”‚ โ”‚ competitions 8 results 3,300 standings predictions 20 โ”‚ โ”‚ categories 11 splits 0 โ”‚ โ”‚ venues 27 source files 33 โ”‚ โ”‚ events 36 โ”‚ โ”‚ races 36 โ”‚ โ”‚ rounds 165 โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ coverage competition year category events rounds results โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ f1_wdc 2024 DRV 12 60 1,200 f1_wdc 2025 DRV 12 60 1,200 f1_wdc 2026 DRV 9 45 900 ``` ### Step 3: ๐Ÿ“Š Backtest the model Every past race priced as of before the weekend, before qualifying and before the race, with track features on and off, scored against the results and against uniform and grid baselines. === "Command" ```bash title="Command" racinglines model backtest kart --demo ``` === "Output" ```text title="Output" progress 0/1 building history (track features on) ๐Ÿ“Š backtest, track features on progress 10/33 2024 R10 rainbow-road progress 20/33 2025 R08 mount-wario progress 30/33 2026 R06 thwomp-ruins progress 33/33 2026 R09 bowser-s-castle ๐Ÿ“Š Track features ON: mean over 32 races โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ market โ”‚ stage โ”‚ model Brier โ”‚ uniform โ”‚ grid โ”‚ skill vs uniform โ”‚ log loss โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ win โ”‚ pre weekend โ”‚ 0.0431 โ”‚ 0.0475 โ”‚ โ€“ โ”‚ โ–‰ +9% โ”‚ 0.1518 โ”‚ โ”‚ โ”‚ pre quali โ”‚ 0.0405 โ”‚ 0.0475 โ”‚ โ€“ โ”‚ โ–ˆโ– +15% โ”‚ 0.1388 โ”‚ โ”‚ โ”‚ pre race โ”‚ 0.0381 โ”‚ 0.0475 โ”‚ 0.0410 โ”‚ โ–ˆโ–‰ +20% โ”‚ 0.1266 โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ podium โ”‚ pre weekend โ”‚ 0.0988 โ”‚ 0.1275 โ”‚ โ€“ โ”‚ โ–ˆโ–ˆโ–Ž +23% โ”‚ 0.3155 โ”‚ โ”‚ โ”‚ pre quali โ”‚ 0.0913 โ”‚ 0.1275 โ”‚ โ€“ โ”‚ โ–ˆโ–ˆโ–Š +28% โ”‚ 0.3058 โ”‚ โ”‚ โ”‚ pre race โ”‚ 0.0772 โ”‚ 0.1275 โ”‚ 0.0824 โ”‚ โ–ˆโ–ˆโ–ˆโ–‰ +39% โ”‚ 0.2699 โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ top10 โ”‚ pre weekend โ”‚ 0.1662 โ”‚ 0.2500 โ”‚ โ€“ โ”‚ โ–ˆโ–ˆโ–ˆโ–Ž +34% โ”‚ 0.5105 โ”‚ โ”‚ โ”‚ pre quali โ”‚ 0.1543 โ”‚ 0.2500 โ”‚ โ€“ โ”‚ โ–ˆโ–ˆโ–ˆโ–Š +38% โ”‚ 0.4897 โ”‚ โ”‚ โ”‚ pre race โ”‚ 0.1295 โ”‚ 0.2500 โ”‚ 0.1345 โ”‚ โ–ˆโ–ˆโ–ˆโ–ˆโ–Š +48% โ”‚ 0.4353 โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ ๐Ÿ favourite won 34% of 32 races ยท rank correlation 0.83 ยท mean winner probability 22.7% best call 2024 R04 Royal Raceway: Donkey Kong won at 48.6% upset 2024 R08 Mount Wario: Donkey Kong won at 1.7% (favourite Peach) progress 0/1 building history (track features off) ๐Ÿ“Š backtest, track features off progress 10/33 2024 R10 rainbow-road progress 20/33 2025 R08 mount-wario progress 30/33 2026 R06 thwomp-ruins progress 33/33 2026 R09 bowser-s-castle ๐Ÿ“Š Track features OFF: mean over 32 races โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ market โ”‚ stage โ”‚ model Brier โ”‚ uniform โ”‚ grid โ”‚ skill vs uniform โ”‚ log loss โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ win โ”‚ pre weekend โ”‚ 0.0437 โ”‚ 0.0475 โ”‚ โ€“ โ”‚ โ–Š +8% โ”‚ 0.1629 โ”‚ โ”‚ โ”‚ pre quali โ”‚ 0.0407 โ”‚ 0.0475 โ”‚ โ€“ โ”‚ โ–ˆโ– +14% โ”‚ 0.1391 โ”‚ โ”‚ โ”‚ pre race โ”‚ 0.0377 โ”‚ 0.0475 โ”‚ 0.0410 โ”‚ โ–ˆโ–ˆ +21% โ”‚ 0.1240 โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ podium โ”‚ pre weekend โ”‚ 0.1033 โ”‚ 0.1275 โ”‚ โ€“ โ”‚ โ–ˆโ–‰ +19% โ”‚ 0.3356 โ”‚ โ”‚ โ”‚ pre quali โ”‚ 0.0915 โ”‚ 0.1275 โ”‚ โ€“ โ”‚ โ–ˆโ–ˆโ–Š +28% โ”‚ 0.3104 โ”‚ โ”‚ โ”‚ pre race โ”‚ 0.0768 โ”‚ 0.1275 โ”‚ 0.0824 โ”‚ โ–ˆโ–ˆโ–ˆโ–‰ +40% โ”‚ 0.2650 โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ top10 โ”‚ pre weekend โ”‚ 0.1879 โ”‚ 0.2500 โ”‚ โ€“ โ”‚ โ–ˆโ–ˆโ– +25% โ”‚ 0.5659 โ”‚ โ”‚ โ”‚ pre quali โ”‚ 0.1573 โ”‚ 0.2500 โ”‚ โ€“ โ”‚ โ–ˆโ–ˆโ–ˆโ–‹ +37% โ”‚ 0.4944 โ”‚ โ”‚ โ”‚ pre race โ”‚ 0.1296 โ”‚ 0.2500 โ”‚ 0.1345 โ”‚ โ–ˆโ–ˆโ–ˆโ–ˆโ–Š +48% โ”‚ 0.4326 โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ ๐Ÿ favourite won 38% of 32 races ยท rank correlation 0.83 ยท mean winner probability 23.1% best call 2024 R04 Royal Raceway: Donkey Kong won at 52.3% upset 2024 R08 Mount Wario: Donkey Kong won at 1.6% (favourite Peach) Per-race rows -> /home/user/racinglines-public/data/demo/kart/runs/f1/backtests/backtest_20261014_0506.csv ``` ### Step 4: ๐Ÿ”ฎ Forecast the rest of the season The next races (Rainbow Road is a sprint weekend) and both championships; --save stores the run the book and the web app read. === "Command" ```bash title="Command" racinglines model forecast kart --demo --save ``` === "Output" ```text title="Output" ๐Ÿ”ฎ forecast 2026 ยท cutoff 2026-10-14 05:06 UTC ยท latest results 2026-10-04 14:00 ๐Ÿ R10 Rainbow Road Grand Prix (18 Oct) โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ driver โ”‚ team โ”‚ win โ”‚ โ”‚ podium โ”‚ โ”‚ top 10 โ”‚ DNF โ”‚ exp pts โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Mario โ”‚ mushroom โ”‚ 26.4% โ”‚ โ–ˆโ–ˆโ–ˆโ–‹ โ”‚ 58.7% โ”‚ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ– โ”‚ 95.0% โ”‚ 3.2% โ”‚ 15.1 โ”‚ โ”‚ Luigi โ”‚ mushroom โ”‚ 18.8% โ”‚ โ–ˆโ–ˆโ–‹ โ”‚ 49.7% โ”‚ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–‰ โ”‚ 93.8% โ”‚ 3.1% โ”‚ 13.4 โ”‚ โ”‚ Bowser โ”‚ koopa โ”‚ 14.4% โ”‚ โ–ˆโ–ˆ โ”‚ 40.2% โ”‚ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–‹ โ”‚ 82.2% โ”‚ 13.9% โ”‚ 11.2 โ”‚ โ”‚ Peach โ”‚ royal โ”‚ 9.9% โ”‚ โ–ˆโ– โ”‚ 33.1% โ”‚ โ–ˆโ–ˆโ–ˆโ–ˆโ–‹ โ”‚ 86.7% โ”‚ 5.5% โ”‚ 10.2 โ”‚ โ”‚ Daisy โ”‚ royal โ”‚ 8.3% โ”‚ โ–ˆโ– โ”‚ 29.6% โ”‚ โ–ˆโ–ˆโ–ˆโ–ˆโ– โ”‚ 84.4% โ”‚ 5.9% โ”‚ 9.5 โ”‚ โ”‚ Donkey Kong โ”‚ kong โ”‚ 8.0% โ”‚ โ–ˆ โ”‚ 27.4% โ”‚ โ–ˆโ–ˆโ–ˆโ–Š โ”‚ 85.8% โ”‚ 3.5% โ”‚ 9.3 โ”‚ โ”‚ Bowser Jr. โ”‚ koopa โ”‚ 6.7% โ”‚ โ–‰ โ”‚ 23.6% โ”‚ โ–ˆโ–ˆโ–ˆโ–Ž โ”‚ 75.2% โ”‚ 13.7% โ”‚ 8.1 โ”‚ โ”‚ Diddy Kong โ”‚ kong โ”‚ 2.8% โ”‚ โ– โ”‚ 12.3% โ”‚ โ–ˆโ–‹ โ”‚ 72.9% โ”‚ 3.3% โ”‚ 5.8 โ”‚ โ”‚ Yoshi โ”‚ yoshi โ”‚ 1.6% โ”‚ โ– โ”‚ 7.7% โ”‚ โ–ˆ โ”‚ 60.1% โ”‚ 7.3% โ”‚ 4.2 โ”‚ โ”‚ Rosalina โ”‚ comet โ”‚ 1.2% โ”‚ โ– โ”‚ 5.9% โ”‚ โ–Š โ”‚ 55.5% โ”‚ 5.6% โ”‚ 3.6 โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ ๐Ÿ R11 Wario Stadium Grand Prix (01 Nov) โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ driver โ”‚ team โ”‚ win โ”‚ โ”‚ podium โ”‚ โ”‚ top 10 โ”‚ DNF โ”‚ exp pts โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Mario โ”‚ mushroom โ”‚ 24.4% โ”‚ โ–ˆโ–ˆโ–ˆโ– โ”‚ 59.3% โ”‚ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–Ž โ”‚ 95.4% โ”‚ 3.0% โ”‚ 15.0 โ”‚ โ”‚ Luigi โ”‚ mushroom โ”‚ 20.7% โ”‚ โ–ˆโ–ˆโ–‰ โ”‚ 52.9% โ”‚ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ– โ”‚ 94.8% โ”‚ 3.0% โ”‚ 14.0 โ”‚ โ”‚ Peach โ”‚ royal โ”‚ 15.6% โ”‚ โ–ˆโ–ˆโ– โ”‚ 44.2% โ”‚ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ– โ”‚ 90.8% โ”‚ 5.9% โ”‚ 12.4 โ”‚ โ”‚ Bowser โ”‚ koopa โ”‚ 12.9% โ”‚ โ–ˆโ–Š โ”‚ 37.3% โ”‚ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ– โ”‚ 82.2% โ”‚ 14.0% โ”‚ 10.8 โ”‚ โ”‚ Daisy โ”‚ royal โ”‚ 12.1% โ”‚ โ–ˆโ–‹ โ”‚ 36.9% โ”‚ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ– โ”‚ 89.1% โ”‚ 5.7% โ”‚ 11.2 โ”‚ โ”‚ Bowser Jr. โ”‚ koopa โ”‚ 4.6% โ”‚ โ–‹ โ”‚ 19.1% โ”‚ โ–ˆโ–ˆโ–‹ โ”‚ 75.1% โ”‚ 13.7% โ”‚ 7.3 โ”‚ โ”‚ Donkey Kong โ”‚ kong โ”‚ 4.2% โ”‚ โ–Œ โ”‚ 18.4% โ”‚ โ–ˆโ–ˆโ–Œ โ”‚ 82.0% โ”‚ 3.1% โ”‚ 7.6 โ”‚ โ”‚ Yoshi โ”‚ yoshi โ”‚ 2.1% โ”‚ โ–Ž โ”‚ 11.0% โ”‚ โ–ˆโ–Œ โ”‚ 69.3% โ”‚ 7.4% โ”‚ 5.4 โ”‚ โ”‚ Diddy Kong โ”‚ kong โ”‚ 1.0% โ”‚ โ– โ”‚ 6.1% โ”‚ โ–Š โ”‚ 61.1% โ”‚ 3.6% โ”‚ 4.0 โ”‚ โ”‚ Birdo โ”‚ yoshi โ”‚ 0.9% โ”‚ โ– โ”‚ 5.3% โ”‚ โ–‹ โ”‚ 56.3% โ”‚ 7.3% โ”‚ 3.6 โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ ๐Ÿ† 2026 drivers' championship โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ driver โ”‚ points โ”‚ expected โ”‚ champion โ”‚ โ”‚ top 3 โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Luigi โ”‚ 191 โ”‚ 234 โ”‚ 99.8% โ”‚ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–‰ โ”‚ 100.0% โ”‚ โ”‚ Mario โ”‚ 134 โ”‚ 182 โ”‚ 0.2% โ”‚ โ”‚ 99.1% โ”‚ โ”‚ Peach โ”‚ 106 โ”‚ 141 โ”‚ 0.0% โ”‚ โ”‚ 60.5% โ”‚ โ”‚ Bowser โ”‚ 99 โ”‚ 135 โ”‚ 0.0% โ”‚ โ”‚ 39.9% โ”‚ โ”‚ Daisy โ”‚ 62 โ”‚ 95 โ”‚ 0.0% โ”‚ โ”‚ 0.2% โ”‚ โ”‚ Donkey Kong โ”‚ 57 โ”‚ 85 โ”‚ 0.0% โ”‚ โ”‚ 0.2% โ”‚ โ”‚ Bowser Jr. โ”‚ 60 โ”‚ 85 โ”‚ 0.0% โ”‚ โ”‚ 0.1% โ”‚ โ”‚ Koopa Troopa โ”‚ 55 โ”‚ 58 โ”‚ 0.0% โ”‚ โ”‚ 0.0% โ”‚ โ”‚ Birdo โ”‚ 36 โ”‚ 48 โ”‚ 0.0% โ”‚ โ”‚ 0.0% โ”‚ โ”‚ Diddy Kong โ”‚ 28 โ”‚ 46 โ”‚ 0.0% โ”‚ โ”‚ 0.0% โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ constructors team points expected champion โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Mushroom Racing 325 416 100.0% โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ Royal Racing 168 236 0.0% Koopa Kart Works 159 220 0.0% Kong Jungle Racing 85 132 0.0% Yoshi Island GP 62 91 0.0% finishing model coef {'g': 0.527, 'g_ease': -0.149, 'rp_rel': 0.041, 'rp_ease': 0.051, 'qp_rel': 0.08, 'street_g': 0.0} sigma 0.155; season drift (as-of) {'team_sd': 0.002652025069557153, 'driver_sd': 0.0005339299639313828} Saved forecast run 2. ``` ### Step 5: ๐Ÿ Run a live private book Bowser's Castle (round 9) replayed on a simulated clock: the maker's book opens before practice, reprices after each session from the model's stage runs, 100 simulated takers trade against it, the book closes at lights out and settles from the results. === "Command" ```bash title="Command" racinglines live run kart/demo-2026-09 --demo --simulate --no-fetch ``` === "Output" ```text title="Output" pre-weekend: priced (run #3) 2026-10-02T10:30:00+00:00 2026-09 pre-weekend: 80 markets, 54 quoted, 0 crowd fills, maker P&L +24.73 โ•ญโ”€ ๐Ÿšฆ Bowser's Castle Grand Prix 2026 (synthetic) ยท pre-weekend (1 of 7 ยท 2026-10-02T10:30 UTC) โ”€โ•ฎ โ”‚ โ”‚ โ”‚ driver fair move bid ask Polymarket Kalshi inventory โ”‚ โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”‚ Mario 27.6% โ–ˆโ–ˆโ–ˆโ–Ž 24.0% 31.0% 32.5% 36.0% -81 โ”‚ โ”‚ Luigi 21.4% โ–ˆโ–ˆโ–Œ 18.0% 25.0% 11.1% 8.0% โ€“ โ”‚ โ”‚ Daisy 20.5% โ–ˆโ–ˆโ– 17.0% 24.0% 6.1% 5.7% โ€“ โ”‚ โ”‚ Peach 18.2% โ–ˆโ–ˆโ– 15.0% 22.0% 10.4% 11.2% โ€“ โ”‚ โ”‚ Bowser 3.6% โ– 1.0% 8.0% 10.2% 10.5% -357 โ”‚ โ”‚ Bowser Jr. 2.1% โ–Ž โ€“ 6.0% 1.8% 2.1% โ€“ โ”‚ โ”‚ Yoshi 1.6% โ– โ€“ 5.0% 1.6% 1.9% โ€“ โ”‚ โ”‚ Koopa Troopa 1.2% โ– โ€“ 5.0% 7.2% 11.2% โ€“ โ”‚ โ”‚ โ”‚ โ”‚ ๐Ÿ‘ฅ crowd: 0 fills this update ยท 0 in all ยท $0 traded ยท 0 of 100 takers still betting โ”‚ โ”‚ ๐Ÿ’ฐ maker P&L +24.73 (crowd +0.00, picks +24.73) โ”‚ โ”‚ next: after FP1 at 2026-10-02T13:00 UTC โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ after FP1: priced (run #4) 2026-10-02T13:00:00+00:00 2026-09 after FP1: 80 markets, 44 quoted, 4 crowd fills, maker P&L -75.09 โ•ญโ”€ ๐Ÿ”„ Bowser's Castle Grand Prix 2026 (synthetic) ยท after FP1 (2 of 7 ยท 2026-10-02T13:00 UTC) โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ โ”‚ โ”‚ driver fair move bid ask Polymarket Kalshi inventory โ”‚ โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”‚ Mario 29.1% โ–ˆโ–ˆโ–ˆโ– โ–ฒ 1.5 26.0% 32.0% 32.5% 36.0% -66 โ”‚ โ”‚ Bowser 20.1% โ–ˆโ–ˆโ– โ–ฒ 16.4 17.0% 23.0% 10.2% 10.5% -357 โ”‚ โ”‚ Luigi 19.3% โ–ˆโ–ˆโ–Ž โ–ผ 2.1 16.0% 22.0% 11.1% 8.0% โ€“ โ”‚ โ”‚ Peach 16.0% โ–ˆโ–‰ โ–ผ 2.2 13.0% 19.0% 10.4% 11.2% โ€“ โ”‚ โ”‚ Daisy 11.1% โ–ˆโ–Ž โ–ผ 9.5 8.0% 14.0% 6.1% 5.7% โ€“ โ”‚ โ”‚ Koopa Troopa 1.9% โ– โ–ฒ 0.6 โ€“ 5.0% 7.2% 11.2% โ€“ โ”‚ โ”‚ Yoshi 0.7% โ–ผ 0.9 โ€“ 4.0% 1.6% 1.9% โ€“ โ”‚ โ”‚ King Boo 0.5% โ–ผ 0.6 โ€“ 4.0% 2.3% 1.8% โ€“ โ”‚ โ”‚ โ”‚ โ”‚ ๐Ÿ‘ฅ crowd: 4 fills this update ยท 4 in all ยท $294 traded ยท 4 of 100 takers still betting โ”‚ โ”‚ ๐Ÿ’ฐ maker P&L -75.09 (crowd -51.91, picks -23.17) โ”‚ โ”‚ ๐Ÿ fp1: P1 Mario ยท P2 Bowser ยท P3 Luigi โ”‚ โ”‚ next: after FP2 at 2026-10-02T16:30 UTC โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ โ€ฆ 79 lines cut (showing the first 39 and last 28 of 146) โ€ฆ 2026-10-04T17:00:00+00:00 2026-09 results: 80 markets, 0 quoted, 0 crowd fills, maker P&L -222.25 โ•ญโ”€ ๐Ÿ Bowser's Castle Grand Prix 2026 (synthetic) ยท results (7 of 7 ยท 2026-10-04T17:00 UTC) โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ โ”‚ โ”‚ driver fair move bid ask Polymarket Kalshi inventory โ”‚ โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”‚ Luigi โœ… 31.4% โ–ˆโ–ˆโ–ˆโ–Š โ–ฒ 4.5 โ€“ โ€“ 11.1% 8.0% -13 โ”‚ โ”‚ Daisy โŒ 20.5% โ–ˆโ–ˆโ– โ–ฒ 8.5 โ€“ โ€“ 6.1% 5.7% -66 โ”‚ โ”‚ Mario โŒ 20.4% โ–ˆโ–ˆโ– โ–ผ 2.2 โ€“ โ€“ 32.5% 36.0% -66 โ”‚ โ”‚ Bowser โŒ 20.0% โ–ˆโ–ˆโ– โ–ฒ 5.3 โ€“ โ€“ 10.2% 10.5% -1,058 โ”‚ โ”‚ Peach โŒ 6.5% โ–Š โ–ผ 12.8 โ€“ โ€“ 10.4% 11.2% -132 โ”‚ โ”‚ King Boo โŒ 0.5% โ–ผ 0.3 โ€“ โ€“ 2.3% 1.8% -2,338 โ”‚ โ”‚ Koopa Troopa โŒ 0.4% โ–ผ 1.4 โ€“ โ€“ 7.2% 11.2% โ€“ โ”‚ โ”‚ Donkey Kong โŒ 0.2% = โ€“ โ€“ 0.8% โ€“ โ€“ โ”‚ โ”‚ โ”‚ โ”‚ ๐Ÿ‘ฅ crowd: 0 fills this update ยท 176 in all ยท $6,048 traded ยท 52 of 100 takers still betting โ”‚ โ”‚ ๐Ÿ’ฐ maker P&L -222.25 (crowd -72.25, picks -150.00) โ”‚ โ”‚ ๐Ÿ race: P1 Luigi ยท P2 Daisy ยท P3 Donkey Kong โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ simulated 2026-09 to 2026-10-04 17:00:00: 7 updates โ•ญโ”€ ๐Ÿ Bowser's Castle Grand Prix 2026 (synthetic) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ opened 2026-10-02T10:30 UTC โ”‚ โ”‚ settled 2026-10-04T17:00 UTC โ”‚ โ”‚ ๐Ÿ’ฐ maker P&L -222.25 โ”‚ โ”‚ from the crowd -72.25 โ”‚ โ”‚ from the picks -150.00 โ”‚ โ”‚ ๐Ÿ‘ฅ fills 176 ($6,048 traded) โ”‚ โ”‚ bettors 83: 31 up, 52 down, best +1,297.32, worst -184.03 โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ ``` !!! tip "Rich output, or plain" `db stats`, `model backtest`, `model forecast`, `live run`, `live report` and `book map|price|settle` print Rich output (colour, tables, probability bars), also when piped. `--plain` on any command gives the plain text; `NO_COLOR=1` keeps the layout and drops the colour codes, which is how these outputs were captured ([CLI: Output](cli.md#output-rich-plain-json)). Measured on a cloud container (one CPU, 2026-10-14, the capture's own timings): the store build 56 s, the backtest 45 s, the forecast 10 s, the live run 36 s, the book 2 s. ## After the live run The rehearsal left a settled event in the store. `live status` lists it, and `live report` writes the event report (Markdown, charts and, with `--pdf`, a PDF, which needs weasyprint or a headless Chrome) under `data/demo/kart/runs/live/demo-2026-09/report/`. === "Command" ```bash title="Command" racinglines live status --demo ``` === "Output" ```text title="Output" demo-2026-09 f1 settled last 2026-10-04T17:00 (0.1 h ago) Bowser's Castle Grand Prix 2026 (synthetic) ``` The report, with its own summary of the event and the files it wrote: === "Command" ```bash title="Command" racinglines live report kart/demo-2026-09 --demo ``` === "Output" ```text title="Output" โ•ญโ”€ ๐Ÿ Bowser's Castle Grand Prix 2026 (synthetic) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ opened 2026-10-02T10:30 UTC โ”‚ โ”‚ settled 2026-10-04T17:00 UTC โ”‚ โ”‚ ๐Ÿ’ฐ maker P&L -222.25 โ”‚ โ”‚ from the crowd -72.25 โ”‚ โ”‚ from the picks -150.00 โ”‚ โ”‚ ๐Ÿ‘ฅ fills 176 ($6,048 traded) โ”‚ โ”‚ bettors 83: 31 up, 52 down, best +1,297.32, worst -184.03 โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ ๐Ÿ“„ report files what file โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ md runs/live/demo-2026-09/report/report.md html runs/live/demo-2026-09/report/report.html pnl.svg runs/live/demo-2026-09/report/pnl.svg scorecard.svg runs/live/demo-2026-09/report/scorecard.svg ``` ## Price a sportsbook's lines The pack carries a generic sportsbook's lines on rounds 10 and 11 (`racinglines/demo/packs/kart/book.toml`), one per F1 pricing feature. `book map` resolves every leg to a race, athletes and a market kind by exact keys; `book price` adds the model's fair, the linked exchange price, the book's implied probability and the EV against each; `book settle` adds each leg's result and payout once the race is in. `--json` on any of them prints the same result as JSON ([Sportsbook slips](sportsbook/slips.md)). === "Command" ```bash title="Command" racinglines book map --demo ``` === "Output" ```text title="Output" demo: the demo store's synthetic data (made-up names, results and prices); nothing is traded book map id selection kind status race reason โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ” win Super Mario race_win mapped 34 win-no Luigi not to win race_win mapped 34 podium Peach race_podium mapped 34 top5 Daisy race_top5 mapped 34 top10 Bowser race_top10 mapped 34 p2 Luigi race_p2 mapped 34 pole Mario race_pole mapped 34 fl Luigi race_fastest_lap mapped 34 h2h Daisy v Peach race_h2h mapped 34 mover Yoshi race_biggest_mover mapped 34 spr-win Mario race_sprint_win mapped 34 spr-pole Luigi race_sprint_pole mapped 34 red No race_red_flag mapped 34 sgp-joint Mario win + Luigi combo mapped 34 podium โ”” 14.1 race_win Mario (f1 mapped 34 2026-10) โ”” 14.2 race_podium Luigi mapped 34 (f1 2026-10) sgp-product Peach podium + combo mapped 34 Daisy top 10 โ”” 15.1 race_podium Peach mapped 34 (f1 2026-10) โ”” 15.2 race_top10 Daisy mapped 34 (f1 2026-10) parlay Mario wins Rainbow combo mapped 34, 35 Road and Wario Stadium โ”” 16.1 race_win Mario (f1 mapped 34 2026-10) โ”” 16.2 race_win Mario (f1 mapped 35 2026-11) typo Maryo race_win unmapped 34 leg 17: driver 'Maryo' is not an exact name in race 34's field โ”” 17 race_win (f1 unmapped 34 driver 'Maryo' is 2026-10) not an exact name in race 34's field book_demo ยท event 2026-10 ยท f1 ยท captured 2026-10-15T09:00Z ยท odds decimal ยท USD โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ unmapped lines โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ typo โ”‚ โ”‚ exact keys only: fix the book file or its [aliases] โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ ``` Every leg mapped by its exact keys. Now the prices: === "Command" ```bash title="Command" racinglines book price --demo ``` === "Output" ```text title="Output" demo: the demo store's synthetic data (made-up names, results and prices); nothing is traded book price model id selection odds book model market EV model EV market method โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ” win Super 3.20 31.2% 26.4% 65.4% -15.6% +109.3% single Mario win-no Luigi not 1.30 76.9% 81.2% 87.2% +5.6% +13.4% single to win podium Peach 2.40 41.7% 33.1% 11.6% -20.5% -72.2% single top5 Daisy 1.90 52.6% 50.2% โ€“ -4.6% โ€“ single top10 Bowser 1.25 80.0% 82.2% โ€“ +2.7% โ€“ single p2 Luigi 4.50 22.2% โ€“ 32.8% โ€“ +47.6% single pole Mario 2.75 36.4% 35.0% 66.3% -3.9% +82.3% single fl Luigi 5.00 20.0% โ€“ โ€“ โ€“ โ€“ single h2h Daisy v 2.10 47.6% 47.0% 41.5% -1.4% -12.8% single Peach mover Yoshi 6.00 16.7% 8.6% โ€“ -48.5% โ€“ single spr-win Mario 2.90 34.5% 24.8% โ€“ -28.0% โ€“ single spr-pole Luigi 4.00 25.0% 16.1% โ€“ -35.6% โ€“ single red No 1.45 69.0% โ€“ โ€“ โ€“ โ€“ single sgp-joint Mario win 4.20 23.8% 13.1% 40.0% -44.9% +68.1% product + Luigi podium โ”” 14.1 race_win โ€“ 26.4% 65.4% Mario (f1 polymarket 2026-10) โ”” 14.2 race_podiโ€ฆ โ€“ 49.7% 61.2% Luigi (f1 polymarket 2026-10) sgp-product Peach 2.50 40.0% 28.0% โ€“ -30.1% โ€“ product podium + Daisy top 10 โ”” 15.1 race_podiโ€ฆ โ€“ 33.1% 11.6% Peach (f1 polymarket 2026-10) โ”” 15.2 race_top10 โ€“ 84.4% โ€“ Daisy (f1 2026-10) parlay Mario wins 9.60 10.4% 6.4% 35.9% -38.2% +244.7% single x Rainbow single Road and Wario Stadium โ”” 16.1 race_win 3.2 31.2% 26.4% 65.4% Mario (f1 polymarket 2026-10) โ”” 16.2 race_win 3.0 33.3% 24.4% 54.9% Mario (f1 polymarket 2026-11) typo Maryo โ€“ โ€“ โ€“ โ€“ โ€“ โ€“ book_demo ยท event 2026-10 ยท f1 ยท captured 2026-10-15T09:00Z ยท odds decimal ยท USD โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ flags โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ sgp-joint: race 34: 2 legs on one race, correlated: EV approximate โ”‚ โ”‚ sgp-joint: market: product of leg prices on one race, correlated: EV approximate โ”‚ โ”‚ sgp-product: race 34: 2 legs on one race, correlated: EV approximate โ”‚ โ”‚ parlay: legs on 2 races: independent across races (product) โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ unmapped lines โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ typo โ”‚ โ”‚ exact keys only: fix the book file or its [aliases] โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ assumptions โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ โ€ข EV is per unit staked: probability x decimal payout - 1; decimal payout = 1 / the book's โ”‚ โ”‚ implied probability. โ”‚ โ”‚ โ€ข Legs on different races are independent: the slip probability is the product of their โ”‚ โ”‚ probabilities. โ”‚ โ”‚ โ€ข Legs on the same race are priced jointly from simulations when they are available (passed in, โ”‚ โ”‚ or a stored combo run with exactly these legs); otherwise the product of the marginals, flagged โ”‚ โ”‚ 'correlated: EV approximate'. โ”‚ โ”‚ โ€ข The market's slip probability is the product of its legs' prices: no exchange lists the slip โ”‚ โ”‚ itself. โ”‚ โ”‚ โ€ข Model and market are shown side by side, never blended (owner, 2026-10-07). โ”‚ โ”‚ โ€ข The market price is the freshest linked exchange's mid (bid/ask midpoint, else its last price, โ”‚ โ”‚ else the tape's). โ”‚ โ”‚ blend: none (owner, 2026-10-07; docs/sportsbook/slips.md) โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ ``` And the settlement: === "Command" ```bash title="Command" racinglines book settle --demo ``` === "Output" ```text title="Output" demo: the demo store's synthetic data (made-up names, results and prices); nothing is traded book settle id selection odds result payout profit โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ” win Super Mario 3.20 pending โ€“ โ€“ win-no Luigi not to win 1.30 pending โ€“ โ€“ podium Peach 2.40 pending โ€“ โ€“ top5 Daisy 1.90 pending โ€“ โ€“ top10 Bowser 1.25 pending โ€“ โ€“ p2 Luigi 4.50 pending โ€“ โ€“ pole Mario 2.75 pending โ€“ โ€“ fl Luigi 5.00 manual โ€“ โ€“ h2h Daisy v Peach 2.10 pending โ€“ โ€“ mover Yoshi 6.00 pending โ€“ โ€“ spr-win Mario 2.90 pending โ€“ โ€“ spr-pole Luigi 4.00 pending โ€“ โ€“ red No 1.45 manual โ€“ โ€“ sgp-joint Mario win + Luigi podium 4.20 pending โ€“ โ€“ โ”” 14.1 race_win Mario (f1 2026-10) pending โ”” 14.2 race_podium Luigi (f1 2026-10) pending sgp-product Peach podium + Daisy top 10 2.50 pending โ€“ โ€“ โ”” 15.1 race_podium Peach (f1 2026-10) pending โ”” 15.2 race_top10 Daisy (f1 2026-10) pending parlay Mario wins Rainbow Road and Wario Stadium 9.60 pending โ€“ โ€“ โ”” 16.1 race_win Mario (f1 2026-10) pending โ”” 16.2 race_win Mario (f1 2026-11) pending typo Maryo โ€“ โ€“ โ€“ โ€“ book_demo ยท event 2026-10 ยท f1 ยท captured 2026-10-15T09:00Z ยท odds decimal ยท USD โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ unmapped lines โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ typo โ”‚ โ”‚ exact keys only: fix the book file or its [aliases] โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ ``` Rounds 10 and 11 have not been raced in the pack, so every line settles as `pending`. ## Where things go | What | Where | Notes | |---|---|---| | The demo database | `racinglines_demo_kart`, on the same server as `DATABASE_URL` | `RACINGLINES_DEMO_DATABASE_URL` moves it | | The demo data folder | `data/demo/kart/` (gitignored) | the generated FastF1 files under `raw/`, the exchange links under `archive/`, run outputs under `runs/`, the live spec under `live/`; `RACINGLINES_DEMO_DATA` moves it | | The build marker | `data/demo/kart/demo-store.json` | a fingerprint of the pack and its generator: both the database and the folder are rebuilt when the pack changes; delete the marker (or drop the database) to rebuild by hand | Not in the quickstart yet: `strategy replay f1` (the maker replay needs a recorded exchange tape of price history and trades per market; the kart pack carries quotes only, not a tape). ## Rebuild the data yourself The demo is synthetic. To rebuild the real history locally, every source the code ingests is fetched with your own machine's network access, and with your own key where one is needed. Keys are never typed on the command line or committed: put them in your environment, or in a gitignored env file you fill with a hidden prompt, e.g. ```bash # LOCAL (Mac): store a key without echoing it or leaving it in the shell history read -rs -p "WUNDERGROUND_API_KEY: " k && printf 'export WUNDERGROUND_API_KEY=%s\n' "$k" >> .env.local && unset k chmod 600 .env.local && source .env.local # .env.local: add it to .git/info/exclude if it isn't ignored ``` | Source | What | Your own key? | Commands | Code | |---|---|---|---|---| | F1 live-timing archive (via FastF1) | F1 sessions: results, laps, schedule | No | `racinglines data fetch f1 --years 2020-2026`, then `racinglines data ingest f1` | `racinglines/sources/fastf1/fetch.py`, `ingest.py` | | ChronoRace | UCI downhill results | No (the results key comes from ChronoRace's public page data) | `racinglines data download mtb_dh`, then `racinglines data ingest mtb_dh` | `racinglines/sources/chronorace/download.py`, `ingest.py` | | NASCAR content feeds (cf.nascar.com) | NASCAR Cup results and laps | No | `racinglines data fetch nascar`, then `racinglines data ingest nascar` | `racinglines/sources/nascar/fetch.py` | | MotoGP results API (api.motogp.pulselive.com) | MotoGP classifications | No | `racinglines data fetch motogp`, then `racinglines data ingest motogp` | `racinglines/sources/motogp/fetch.py` | | Polymarket (Gamma API) | market links, prices, trades | No (public market data) | `racinglines markets sync`, `racinglines markets history`, `racinglines markets trades` | `racinglines/markets/polymarket/sync.py` | | Kalshi (Trade API v2, market data) | market links, prices, trades | No for market data; a key (`KALSHI_API_KEY_ID`, `KALSHI_PRIVATE_KEY_PATH`, from your Kalshi account's API keys page) only for the portfolio and order endpoints, which a rebuild doesn't use | `racinglines markets --exchange kalshi sync` (then `history`, `trades`) | `racinglines/markets/kalshi/client.py`, `trade.py` | | Open-Meteo | weather forecasts per event | No | `racinglines weather fetch` | `racinglines/weather/open_meteo.py` | | Weather Underground | weather forecasts (optional source) | Yes: `WUNDERGROUND_API_KEY`, the key a Weather Underground personal weather station owner gets; untested (no key has been probed) | `racinglines weather probe`, `racinglines weather fetch` | `racinglines/weather/wunderground.py` | | IndyCar, WEC, SailGP | results (sources present, not wired into an ingest) | unknown | none yet | `racinglines/sources/indycar/`, `wec/`, `sailgp/` | Recorded exchange history older than what the exchanges still serve exists only on the VM: a rebuild has whatever the exchanges return today. Respect each source's terms of use (e.g. `sports/motogp.toml` `[results].terms`) and its rate limits; the fetchers pace themselves and are safe to re-run. ## Next steps
- :material-console: **CLI reference** --- Every group and command, with its `-h` output and a real run where one is captured. [:octicons-arrow-right-24: CLI reference](cli.md) - :material-package-variant: **Demo data packs** --- What `--demo` does, what a pack is, the kart pack, and how to add one of your own. [:octicons-arrow-right-24: Demo data packs](demo.md) - :material-robot: **Ask Claude instead** --- The MCP server: the same data and simulations as typed tools for Claude Code, Claude Desktop or the CLI. [:octicons-arrow-right-24: MCP server](mcp.md) - :material-web: **The web app** --- Markets, Trade, History and Lab at racinglines.bet, and how to run the app yourself. [:octicons-arrow-right-24: Web app](webapp.md)
--- # Demo data packs > `--demo [PACK]` on any command runs that command, unchanged, on a demo store: a separate Postgres database and data folder filled from a data pack by the real pipeline. The commands to run are in the [Quickstart](quickstart.md). This page is how a demo store works, what the bundled `kart` pack holds, how the hosted demo store serves it, and how to add a pack of your own. !!! note "No demo branch anywhere" There is no demo code path in any command, model or pipeline: the backtest is `pricing.backtest`, the forecast `pricing.forecast`, the live book `pipelines/live_f1.py` with the real crowd and quoting, the book `books/slips.py`. `--demo` only changes where the data comes from. ## What `--demo` does One resolver (`racinglines/cli/source.py`, called by `racinglines/cli/__init__.py` before anything else) takes `--demo [PACK]` out of the arguments and points the process at the pack's store: | Setting | Demo value | Default location | |---|---|---| | `DATABASE_URL` | the pack's database, on the same server as the configured one | `racinglines_demo_` (`RACINGLINES_DEMO_DATABASE_URL` overrides) | | `RACINGLINES_DATA` | the pack's data folder: raw files, archives, run outputs, live specs | `data/demo//` (gitignored; `RACINGLINES_DEMO_DATA` overrides) | | `RACINGLINES_OFFLINE=1` | FastF1's servers are never called: the store's files are the record | (a general switch, also for machines without FastF1 access) | Then the command runs as it always does. `PACK` defaults to `kart`; `--demo=PACK` works too. The first `--demo` command builds the store when it is missing or when the pack has changed (a Rich progress bar; about a minute). The store build is logged in the store's own data change log, as any ingest is: === "Command" ```bash title="Command" racinglines db changes --demo ``` === "Output" ```text title="Output" 2026-10-14 05:06 f1 forecast f1 forecast run 2: 2026-10, 2026-11, 2026-12, baseline, 10000 sims (root@vm) 2026-10-14 05:05 f1 demo demo store built from pack kart (synthetic f1 data) (root@vm) 2026-10-14 05:05 f1 forecast f1 forecast run 1: 2026-10, 2026-11, 2026-12, baseline, 2000 sims (root@vm) ``` A pack can name its sport differently from the schema it is stored under, so its commands read naturally: the kart pack's `sport_name = "kart"` is why `racinglines model forecast kart --demo` is the F1 forecast, with F1's options: === "Command" ```bash title="Command" racinglines model forecast kart --demo -h ``` === "Output" ```text title="Output" usage: racinglines model forecast f1 [-h] [--year YEAR] [--sims SIMS] [--save] [--top TOP] [--no-track] [--scenario LABEL] options: -h, --help show this help message and exit --year YEAR --sims SIMS --save --top TOP --no-track --scenario LABEL Save as kind='scenario' (not used for live prices until promoted in the web app). ``` ## What a pack is A folder with a `pack.toml` manifest, bundled under `racinglines/demo/packs//` or in a folder named by `RACINGLINES_DEMO_PACKS` (several, separated by `:`). The manifest holds data and the names of real commands only: | Key | What | |---|---| | `name`, `title`, `about` | the pack's name (what `--demo NAME` takes) and description | | `sport` | an **existing** sport schema (`sports/.toml`) the data is stored under: no new sport, no new schema | | `sport_name` | optional: what the quickstart's commands call the sport (`kart`, read as `f1`) | | `files` | a folder copied as is into the data folder (e.g. `raw/...` files a real ingest reads, live specs under `live/`) | | `[generator]` | optional: `entry = "module:function"` writing more data files into the data folder, and its `input` | | `[load] commands` | the real `racinglines ...` commands that load the data into the database, in order | | `[book] file` | the sportsbook book `racinglines book price --demo` prices when no FILE is given | | `[remote] mcp_url` | the pack's hosted demo server, for `--demo --remote` ([below](#the-hosted-demo-store)) | | `tagline` | optional: a line printed once the store is ready (a pack's flavour lives here, never in a command) | | `[[quickstart]]` | the pack's quickstart: `title`, `run` (the command), `about`, optional `section` (steps group under one heading per section, in first-seen order; none: one list) and `record = false` for a step that is shown but never run; rendered into the [Quickstart](quickstart.md) by `scripts/build_quickstart.py` (`--commands PACK [--section NAME]` lists them) and replayed by the web app's `/docs/quickstart/term` page (`Pack.sections()` in `racinglines/demo/store.py`) | The store build (`racinglines/demo/store.py`), in order: 1. create the database (its name must contain `demo`), Alembic upgrade head and the seed (`racinglines db init`); 2. copy the files; 3. run the generator; 4. run each load command as a subprocess on the store; 5. record a `data_changes` line and write a marker (`demo-store.json`, a fingerprint of the pack and its generator). Adding a pack is adding a folder: no command, flag, schema, sport file or code path changes. `tests/test_demo_store.py` builds a second, tiny pack under `mtb_dh` (synthetic ChronoRace result files loaded by `racinglines data ingest mtb_dh`) and runs its backtest through the same code. ## The kart pack `racinglines/demo/packs/kart/`: a synthetic Formula 1 world with a Mario Kart grid, stored under the F1 schema. - `world.toml`, the generator's input: three seasons (2024-2026, twelve rounds each, 2026's rounds 1-9 raced, sprints at rounds 3, 6 and 10), 20 drivers in 10 teams (Mario, Luigi, Peach, Bowser, ...), twelve tracks (Mario Kart 8 Deluxe's Mario Kart Stadium, Rainbow Road, Bowser's Castle, ...), each team's car pace and the driver offsets, the tracks' lap times (5 % off each course's fastest 150cc world-record lap, from mkwrs.com, so no generated lap beats a record), sector shares, trap speeds, how hard passing is and how often a safety car comes out. Sector speeds and passing come from course profiles where there is one, and how much each team gains on fast or tight tracks from its drivers' in-game stats. These are the synthetic world's hidden truth; the real model never reads them, it fits the generated laps. `--demo kart-classic` is the first kart world, with made-up F1-length lap times. - `racinglines/demo/mk_demo/generate.py` writes FastF1-shaped files for every raced session (practice, sprint qualifying, sprint, qualifying, race: results, laps with sectors and speed traps, meta with weather) and each season's schedule, the shapes `sources/fastf1/fetch.py` saves; and quotes from a synthetic Polymarket (win, podium, pole, teammates' head-to-heads) and Kalshi (win, podium, 2nd place) on rounds 9-11, in the file `racinglines data pm-links-export` writes. Seeded: the same input gives the same files. - The load: `data ingest f1` (the real FastF1 ingest: events, results, laps, track profiles), `model forecast f1 --save` (files the unraced rounds as scheduled races), `data pm-links-import f1` for each exchange. - `files/live/f1/demo-2026-09.toml`: the live rehearsal's launch spec (round 9, already raced, so the book settles): `[live.crowd] takers = 100`. - `book.toml`: a generic sportsbook's lines on rounds 10 and 11, one per F1 pricing feature of `book price`. The synthetic exchanges are data like the rest: prices drawn around the generator's own odds with an exchange's noise and spread. No real exchange data is in any pack. What the store holds once built, by table: === "Command" ```bash title="Command" racinglines db stats --demo ``` === "Output" ```text title="Output" demo: building the kart pack's store (no database): database racinglines_demo_kart, folder /home/user/racinglines-public/data/demo/kart. Synthetic data, made once (a few minutes). ๐Ÿ”ง demo store 0/7 creating the database ๐Ÿ”ง demo store 1/7 schema and reference data (alembic upgrade head, seed) ๐Ÿ”ง demo store 2/7 the pack's data files ๐Ÿ”ง demo store generating: 2024 R01 Mario Kart Stadium ๐Ÿ”ง demo store generating: 2025 R01 Mario Kart Stadium ๐Ÿ”ง demo store generating: 2026 R01 Mario Kart Stadium ๐Ÿ”ง demo store generating: files written ๐Ÿ”ง demo store generating: exchange odds 2026-09 ๐Ÿ”ง demo store generating: exchange odds 2026-10 ๐Ÿ”ง demo store generating: exchange odds 2026-11 ๐Ÿ”ง demo store 3/7 racinglines data ingest f1 --years 2024-2026 ๐Ÿ”ง demo store 4/7 racinglines model forecast f1 --save --sims 2000 ๐Ÿ”ง demo store 5/7 racinglines data pm-links-import f1 ๐Ÿ”ง demo store 6/7 racinglines data pm-links-import f1 --exchange kalshi ๐Ÿ”ง demo store 7/7 ready demo: the kart store is ready (f1 data; `racinglines db stats --demo kart`) Let's-a go! ๐Ÿ„ โ•ญโ”€ ๐Ÿ“ฆ database racinglines_demo_kart โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ ๐Ÿ“… calendar ๐Ÿ results ๐Ÿ”ฎ model โ”‚ โ”‚ sports 8 athletes 20 model runs 1 โ”‚ โ”‚ leagues 8 athlete identifiers 20 race predictions 60 โ”‚ โ”‚ competitions 8 results 3,300 standings predictions 20 โ”‚ โ”‚ categories 11 splits 0 โ”‚ โ”‚ venues 27 source files 33 โ”‚ โ”‚ events 36 โ”‚ โ”‚ races 36 โ”‚ โ”‚ rounds 165 โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ coverage competition year category events rounds results โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ f1_wdc 2024 DRV 12 60 1,200 f1_wdc 2025 DRV 12 60 1,200 f1_wdc 2026 DRV 9 45 900 ``` ## The hosted demo store !!! warning "Remote access is in testing" racinglines.bet remote access is in testing (#aintcare mode). A review of venue and data-feed terms is pending, so data served here is for testing only. Every command that connects to the hosted server prints this warning on stderr ([Quickstart: Hosted](quickstart.md#which-way-in)). `--demo [PACK] --remote`, or `--demo` with `source = "remote"` in `~/.config/racinglines/cli.toml`, uses the pack's hosted store instead of a local one. The resolver builds nothing locally: it points the command's own `--remote` path at the pack's demo MCP server (`[remote] mcp_url` in `pack.toml`, `RACINGLINES_DEMO_MCP_URL` overrides it) and adds `--remote`. Only the commands the hosted server runs take it: | Command | How it runs on the hosted store | |---|---| | `book map \| price \| settle` | the pack's book sent to the `map_book` / `price_book` / `settle_book` tools | | `model backtest \| forecast f1 \| mtb_dh` | the command's Lab job, queued with `run_job` and followed with `get_job` (`racinglines/cli/remote.py`); the job's options only | | `db stats`, `live run`, `live report` | not available: these need a local store | `model backtest f1 --remote` without `--demo` runs the same way on whichever server `--remote` names. The server is the normal one with `--demo`: `racinglines mcp --http --port 8766 --demo kart` on the VM serves the kart store (its own database `racinglines_demo_kart` and `data/demo/kart/`, built by the same `store.build`), and its job worker runs the jobs on it. Accounts, `rl_` tokens and OAuth sign-ins are read from production's database (`RACINGLINES_MCP_ACCOUNTS_URL`), so the same Pro and admin accounts sign in, and the store has no account rows of its own: jobs are filed without an owner, so every signed-in caller sees the store's jobs and can cancel a queued one (acceptable on a synthetic store). Account-scoped reads (`overview`'s users, `track_record`, `list_positions`, `list_signals`, our maker's quotes in `list_markets`) show nothing to a non-admin caller there, because a caller's id belongs to production's users table, not the store's. `scripts/vm/demo_store.sh` builds it (`build`, backup first) and starts the server (`serve`); the owner runs both and adds the `mcp-demo` hostname to the tunnel. ## Add a pack of your own ### Step 1: Make the folder A folder named after the pack, bundled under `racinglines/demo/packs//` or anywhere on `RACINGLINES_DEMO_PACKS`, with a `pack.toml` naming an existing sport schema. ### Step 2: Bring the data Either files a real ingest reads (`files`), a generator that writes them (`[generator]`), or both. The kart pack's `world.toml` and `generate.py` are the worked example; the tiny `mtb_dh` pack in `tests/test_demo_store.py` is the smallest one. ### Step 3: Name the load commands `[load] commands`, in order: the same `racinglines data ingest ...` and `racinglines model forecast ... --save` a real database gets. ### Step 4: Write the quickstart `[[quickstart]]` entries, one per command. Then `python3 scripts/build_quickstart.py` renders them into the docs, and `python scripts/docs/capture_examples.py` (after adding them to `scripts/docs/examples.toml`) captures their real output for the page. ### Step 5: Run it ```bash # LOCAL (Mac), or any machine with Postgres racinglines db stats --demo # builds the store, then prints what it holds ``` ## Next steps
- :material-rocket-launch: **Quickstart** --- The kart pack's commands with their real outputs, local or hosted. [:octicons-arrow-right-24: Quickstart](quickstart.md) - :material-robot: **MCP server** --- The hosted server the `--remote` commands reach, and how to connect a chat client to it. [:octicons-arrow-right-24: MCP server](mcp.md) - :material-book-open-variant: **Sportsbook slips** --- The book file `book map | price | settle` reads, and what the EV columns mean. [:octicons-arrow-right-24: Sportsbook slips](sportsbook/slips.md)
--- # Contributing Thanks for wanting to help! racinglines is in beta, and we're looking for beta testers and collaborators. This page is a starting point: **more detail is coming.** Questions, ideas or "I'd like to help with X": [hello@racinglines.bet](mailto:hello@racinglines.bet?subject=racinglines%20contributor). ## Data in this repository This repository (`racinglines/racinglines`, private since 2026-10-19; the package source is exported to `racinglines/racinglines-public`) holds **code, docs, schemas and golden test outputs only**. The data it was developed with (raw FastF1 sessions, the Polymarket and Kalshi price and trade archives, database snapshots, the pinned test fixtures) was removed from this repository and its history when it went public on 2026-10-01: some of it isn't ours to republish, and none of it belongs in git. It lives on the production server and in a private bucket. **Test fixtures are available to beta testers and contributors.** Two ways to get them: - **Ask us** at [hello@racinglines.bet](mailto:hello@racinglines.bet?subject=racinglines%20test%20fixtures) for the pinned fixture bundle (about 2 MB). Unpacked into `tests/fixtures/`, the regression suite matches the golden outputs exactly. - **With access to the private repository** (the owner's machines and cloud sessions): `bash scripts/restore_test_fixtures.sh` copies the pinned set from its git into `tests/fixtures/`, untracked. - **Build them yourself** from the original public sources with `python scripts/fetch_test_fixtures.py --refresh` (needs Postgres; the F1 part can take up to an hour because FastF1 is rate limited). Today's data differs a little from the pinned set, so expect some golden tests to differ: that's fine for development. Without fixtures the fixture-based tests are skipped, not failed, and everything else runs. ## Getting set up 1. Python 3.12 and Docker (for Postgres). 2. Clone, then install the pinned environment: ``` git clone https://github.com/racinglines/racinglines racinglines && cd racinglines python -m venv .venv && . .venv/bin/activate && pip install -r requirements.txt && pip install -e . ``` 3. Start the database and check the install: `docker compose up -d && racinglines check`. 4. Run the tests: `python -m pytest -m "not live"` ([Testing](testing.md)). With the fixtures (above), this is the full regression suite. 5. Run the web app locally: `racinglines web`, then open . ## Making a change - Branch off `main`; one topic per pull request. `main` deploys to racinglines.bet through CI on every merge, so only the owner merges. - **New behaviour ships behind a switch that is off by default** (an `RACINGLINES_*` environment variable), and existing outputs stay byte-identical unless the change is meant to move them (then re-baseline with `UPDATE_GOLDEN=1` and explain the diff). - Before opening a PR: `racinglines check`, `python -m pytest -m "not live"` and `mkdocs build --strict`. - Never commit data: `tests/test_no_data_in_git.py` fails the build if you do. - Docs live in `docs/`; parts of `README.md` are generated from them (`python scripts/build_readme.py`). ## Where to start - [Sports and exchanges (status)](coverage.md): what's covered and what isn't yet. - [Adding a sport](add-a-sport.md) and [Exchanges as schemas](exchanges.md): most new venues are a config file. - [Priorities and open items](todo.md): the current list. *More coming: code layout, how the models and backtests fit together, and good first issues.* --- # Web app & trading `racinglines/web/` is the maker/taker web app (FastAPI, server-rendered pages, no JavaScript framework) on top of the [database](database.md). Partial updates (the Live tab's refresh and replay, the Lab's sections and Edge Finder) are [htmx](https://htmx.org) attributes on the templates (`static/htmx.min.js`, vendored); the little browser-side state (open Lab sections, the replay player) is in `static/app.js`. The look is one stylesheet, `static/style.css`, in sections (tokens, base, layout, components, pages); shared pieces (the page head, flashes, KPIs, signed money) are macros in `templates/_macros.html`. A page shows one thing at a time: big pages (Live, Positions, Strategy, a race, a diagnostic, Quotes) split into tabs (`