{% extends "base_public.html" %} {% block title %}Racinglines 101{% endblock %} {% block main_class %}r101 r-seq{% endblock %} {% block content %}
racinglines › 101
The short version of what this demo does, for anyone who just clicked "I'm already confused": how we trade, how the prediction engine works, how we score it, and how to use the app.
We built a computer model that guesses how an F1 race will go (who wins, who makes the podium, who beats their teammate), and we use it to trade on Polymarket, a site where people bet on those questions. There are two ways to trade, and this demo shows both.
Think of a currency exchange booth at an airport. The booth posts two prices: what it pays for your dollars, and what it charges you for them. The booth is the maker. You, walking up and trading at those prices, are the taker.
Posts a price to buy and a slightly higher price to sell, then waits. It earns the small gap between the two, over and over. Its job is to know the fair price better than anyone walking by, and to step aside when it doesn't.
Doesn't post anything. It looks at the prices already on offer and trades only when one looks like a bargain. Its job is to be picky: most of the time, it does nothing.
On Polymarket, a "price" is a probability. If "Norris wins" trades at 30¢, the crowd thinks he has about a 30% chance. If our model says 45%, that's a bargain to a taker. To a maker, it's a sign to quote around 45¢ instead of 30¢, or not at all.
Try the demo opens the pro demo, the maker account running C. The demo taker, which follows A, signs in by name. For the fantasy league alpha every account gets the same app: five strategy styles to follow in the Lab, built from strategies like these, and the Lab's backtests and research.
After each practice and qualifying session, reprices every race market. It buys only when the model and the crowd disagree by 10 points or more (5 for head-to-head markets), sizes the bet by how big the gap is (at most $50 a market), and adjusts as the weekend goes on.
Quotes 2¢ either side of our fair price, 25 shares at a time, leaning against whatever it already holds. It stays out of thin markets, near-certain ones, and any market where the model and the crowd disagree by more than 5 points.
Both were chosen by testing hundreds of setting combinations on past races, then keeping only the ones that made money in both seasons we have market data for.
No. Every strategy takes its lead from the model. A taker only buys the side the model calls cheap, and a maker only quotes around the model's own price, staying out of markets where it and the crowd disagree too much.
A bet can still be sold at a loss. Strategy A re-prices after every session, so if the model changes its mind, A sells. When the market will pay more than the model now thinks the bet is worth, selling is the better deal, whatever A paid for it. If the gap only shrinks, A sells part of the bet to carry less risk. There is no stop-loss: a strategy sells because the model changed, never just because the price moved against it.
Behind every price on this site is one prediction engine. It doesn't know what F1 or downhill is. Each sport comes with a short description of the data it has, and the engine prices whatever it's given: just finishing positions, or every lap and sector time, or every timed run.
| Sport | What the engine reads |
|---|---|
| F1 | Results, qualifying, the starting grid, practice, every lap and every sector |
| Downhill MTB | Every timed run, practice included |
| NASCAR | Results, qualifying and fastest laps |
| MotoGP | Results and qualifying |
More detail means sharper prices, but the steps are the same in every sport: measure how fast everyone is, run the race thousands of times on a computer, and count.
The engine starts by turning past races into a pace for every competitor. Three ideas do most of the work.
F1 gets a richer version. The engine splits pace into the car (shared by both drivers in a team) and the driver (how they compare with their teammate). In our data the car explains about 60% of the spread in qualifying and 86% in race pace. It also learns how each car does on fast and slow sections of track, so it can tell a team that shines in Monza from one that shines in Monaco.
A pace isn't a prediction. Races have crashes, bad starts and lucky safety cars. So the engine runs the race on a computer, over and over: 10,000 times for an F1 race. Each run is one version of Sunday.
A starting grid (the real one once qualifying is over, a simulated one before), each driver's expected pace, a dose of random luck, and a chance of retiring based on the team's recent reliability. Confirmed grid penalties move drivers back before the start.
A car with a bad setup is usually slow for both drivers. So part of the random luck is drawn once per team and shared by both drivers, measured from past races: about half of it in qualifying, a fifth in the race.
Overtaking matters too. At a track where passing is hard, the grid decides more of the result; at one where it's easy, race pace does. The engine learns how much from each circuit's history.
Once the engine has 10,000 versions of the race, every question is a count.
| Market | How it's priced |
|---|---|
| Win | Norris wins 4,500 of 10,000 runs: 45% |
| Podium, top 10 | The share of runs he finishes in the top 3, or top 10 |
| Head-to-head | The share of runs he finishes ahead of the other driver |
| Pole | The share of runs he's first on the simulated grid |
| Championship | Today's points plus every remaining race simulated, many times over |
Because every market comes from the same runs, the prices agree with each other. A driver can't be more likely to win than to finish on the podium. That 45% is the fair price the strategies compare with the market's.
The engine re-prices after every session: each practice, sprint qualifying, the sprint and qualifying. Practice laps sharpen the pace estimates; once qualifying is over, the simulated grid is replaced by the real one. On a sprint weekend the sprint is priced as a race of its own, with its own grid and points.
Prices are always as of a moment. A price made on Friday night only uses what was known on Friday night. That rule is what makes a backtest honest: replaying last season, the engine never sees a result before it happened.
This is an early demo that paper trades. From now through 2027, the two strategies follow real Polymarket F1 markets live, race weekend by race weekend, and record the trades they would make at the real prices. No real orders are placed and no real money moves.
A price is a forecast, so we grade it like one. The main grade is the Brier score: the average squared gap between the chance we gave and what happened, where what happened is 1 if it came true and 0 if it didn't.
Brier = average of (p − y)²
The closest thing in racing to a coin flip is the teammate head-to-head: will driver A finish ahead of driver B? Here is one, worked out. The box runs real Python: edit the numbers and press Run.
{% raw %}forecast 70% beat (0.7 - 1)² = 0.09
forecast 70% lost (0.7 - 0)² = 0.49
forecast 90% beat (0.9 - 1)² = 0.01
forecast 90% lost (0.9 - 0)² = 0.81
forecast 50% beat (0.5 - 1)² = 0.25
coin flip: 0.25 0.25{% endraw %}
A confident miss is expensive: 90% and wrong costs 0.81, nine times what a 70% miss costs over a 70% hit.
The second grade is log loss: minus the log of the chance we gave to what actually happened. Both scores agree on the easy cases. They part ways on confident misses: Brier never goes above 1, but log loss keeps climbing as the chance goes to zero.
{% raw %}chance Brier log loss
99% 0.00 0.01
90% 0.01 0.11
70% 0.09 0.36 #
50% 0.25 0.69 ###
30% 0.49 1.20 #####
10% 0.81 2.30 #########
1% 0.98 4.61 ##################{% endraw %}
| Brier | Log loss | |
|---|---|---|
| A coin flip scores | 0.25 | 0.693 |
| Worst single forecast | 1 | No limit |
| A confident miss is | Punished | Punished hard |
| Best at catching | Overall error | Rare upsets priced too low |
We report both, because they can rank two forecasts differently. Log loss matters most to a market maker: if a long shot we price at 1% really wins 1 time in 20, takers will keep buying it from us.
A Brier score splits into three parts:
Brier = Reliability − Resolution + Uncertainty
To check reliability we group our prices into bands and count how often those drivers won. Here are our 2025 race-win prices:
{% raw %}priced off: n won calibrated: n won
5-10% 246 2.0% 172 2.9%
10-20% 327 19.6% 201 24.4%
20-35% 86 34.9% 109 24.8%
35-50% 13 53.8% 39 41.0%{% endraw %}
Uncorrected (red), the engine was too flat: drivers we priced at 5 to 10% won 2.0% of the time, and the favourites won more often than we said. It gave long shots too much and favourites too little. That's a reliability problem, and it's fixable.
The fix is one number. Raise every win chance to a power a and rescale so they add up to 100% again: with a above 1, favourites gain and long shots shrink, but the order never changes.
q = pa / sum of all pa
{% raw %}a = 1.0: 30.0% 25.0% 20.0% 12.0% 8.0% 5.0%
a = 1.5: 36.2% 27.5% 19.7% 9.2% 5.0% 2.5%
a = 2.3: 44.7% 29.4% 17.6% 5.4% 2.1% 0.7%{% endraw %}
The power is fitted race by race on earlier races only, so a backtest never uses a result to fix the race it came from. Each simulated race is then re-weighted to match, so the podium, top-10 and head-to-head prices move with the win price and stay consistent with it. It worked on the win prices (blue in the chart above): 2025 log loss went from 0.1694 to 0.1627, and 2026 from 0.2244 to 0.2194. It didn't fix every band: 10 to 20% is still priced too low, and 20 to 35% is now priced too high.
The calibration is off by default. The engine's settings and the method were chosen with these seasons in view, so only races after 14 October 2026 are a clean test. Turning it on for good is the owner's call.
The F1 engine against two simple guesses, after qualifying: the grid-only guess (how often each grid slot has won, podiumed or scored points in earlier races) and the uniform guess (everyone gets the same chance). Skill is the share of the uniform guess's error the forecast removes.
{% raw %}market ours grid uniform skill
Win 0.0307 0.0309 0.0471 35%
Podium 0.0692 0.0708 0.1265 45%
Top 10 0.1500 0.1630 0.2500 40%
H2H 0.1960 0.2500 22%{% endraw %}
From F1 evaluation (run 955, the engine's current setup). The engine beats uniform in every season and stage, and every session sharpens it: the average chance it gave the eventual winner rose from 12.1% before practice to 27.5% after qualifying, and to 31.0% with the current setup.
The harder test is the market. On race winners in 2026, our calibrated prices beat Polymarket's log loss (0.2194 against 0.2222). In 2025 the market was sharper (0.1439 against our 0.1627). That gap is why the paper-trading season matters.
The ideas and layout of this part follow the Brier Score Cheat Sheet by @WalrusQuant, from bayesRatings: methodology. The numbers and charts here are our own.
This site, laid out for the fantasy league alpha. Sign up and you get F$1,000 of fantasy money and four tabs; Try the demo shows the same tabs, and can look but not trade. No real money moves, and nothing reaches an exchange.
| Tab | What's on it |
|---|---|
| Markets | The prediction markets now, with our fair probabilities next to each venue's prices, for F1, NASCAR and MotoGP |
| Trade | Pick an F1 market, see its recorded order book, and buy or sell in F$, one immediate-or-cancel order at a time |
| History | Your F$, every trade and order (refused ones with the reason), your strategy's trades, and the leaderboard |
| Lab | Follow one of five strategy styles and choose its sizing; its track record and positions; backtests, the Edge Finder and replays |
Everything the site does runs from one command, racinglines, installed with the Python package. The task comes first and the sport second:
| Command | What it does |
|---|---|
racinglines model backtest kart --demo | Prices every past race as of before it, and scores the prices |
racinglines model forecast kart --demo --save | Simulates the rest of the season and the championships |
racinglines live run kart/demo-2026-09 --demo --simulate --no-fetch | Runs a live private book against 100 simulated takers |
--demo runs the real engine on a made-up Mario Kart season, so you can try it without any race data of your own. Swap kart for
f1, nascar, motogp or mtb_dh once you have the data. To watch it first, the quickstart replay
replays the same commands in your browser.
With a racinglines.bet account the command line also reaches the hosted server: --remote runs the book commands and Lab jobs there,
racinglines remote calls any tool your account may use, and racinglines data pull f1 copies one sport's shared data into your own database.
It's in testing, and every remote command prints a warning that a review of venue and data terms is still pending.
racinglines mcp starts an MCP server, which lets Claude (or any other MCP client) work with the same data and simulations as the site and the
command line. You ask in plain English, and Claude picks the tools:
There are two ways in. Locally, you run the server on your own machine against your own database. Hosted, you connect Claude to racinglines.bet and sign in with your account, and every job it starts is filed under your account. Remote access is still in testing.