Race Pricer In build

Pick any horses from the database, set the race conditions, and get a priced field — for a race that has never been run.

Not built yet. This page is the design and the measured evidence behind it. The numbers below are real — taken from the model files and from live results on this site — and they set the honest expectation for what the tool can and cannot do.

What it costs to price a race that never happened

A hypothetical race has no betting market, so the model loses the tissue — the compiler’s opening price estimate. Measured by masking the unavailable features on the V5 anchor itself, across 13,004 held-out races / 112,805 runners:

−4.3%
Selection accuracy
Ranking mostly survives. Form and ratings do the ordering.
−6.4%
SAold
Price accuracy falls.
R² goes negative
Price level
3.71 → −4.70. The tissue anchors the level, and nothing else replaces it.
What the model is givenSA newSA oldTop‑1
Everything (a real race)3.7144.9365.6237.13
No preview comments (control)4.1144.7865.2437.11
A race that never happened−4.7041.9761.4235.54
…but you supply a tissue4.7844.8865.3237.13

If you want a ranking, you lose little. If you want a price, the level is the thing you lose. The preview-comment row is the control: masking 111 comment features moves selection accuracy by 0.02 — they are not what a hypothetical race is missing. The market is.

One input changes everything

If you supply a tissue price for each runner, 80 of the 92 missing features become computable — the tissue’s ranks and spreads, every interaction built on it, and the overround, which is just the book added up. That recovers 100% of the selection-accuracy gap (35.54 → 37.13, exactly the figure for a real race), 98% of SA new and 93% of SAold.

Read the R² as parity, not improvement — this tool does not beat the live model, it catches up with it. So the real distinction is not which stage of the tool you are in, it is whether you give it a price to work from: without one you get a trustworthy running order and a shaky level; with one you get the model at full strength. It is also the most interesting thing you can do here — what if this horse were 5/1?

Two honesty notes. These are single-anchor figures: the 69.13 R² published elsewhere on this site is the calibrated five-model stack, and a single model has no calibrated price level, so the two numbers are not comparable. And an earlier version of this page put the cost at −25% R² and −1.4% selection, with SAold improving by 1.8%. That came from comparing against a different model that happens not to use the tissue, rather than removing the tissue from this one — it measured a model swap. The SAold figure had the wrong sign: it falls, it does not rise.

Why it can be fast

The daily pipeline budgets 80–110 minutes per race date, which is why this was assumed impossible. That time is spent building features for a whole card, not predicting. Scoring one race is a single forward pass through a frozen model — milliseconds. Separate the lookup from the computation and the tool is interactive.

Where the 2,340 features come from

ClassCountHow the pricer gets it
Horse history1,455Looked up — already computed nightly
Race conditions351You set these
Field composition102Recomputed each time you add or remove a horse
Comment‑derived432216 imputed from the horse’s own past, 108 derived from conditions, 108 left missing

95.4% of features are available or derivable. The preview-comment features carry just 0.09% of the model’s decision weight — they are not the problem. The tissue, at 12.83%, is.

How a price gets made

pick horses ─► resolve to horse_code └─► assemble 2,340 features per runner ├ history look up ├ field compute from the chosen set ├ condition from what you set └ comment impute / derive / leave missing └─► frozen model, one forward pass └─► normalise: the field sums to 100% └─► check it is not extrapolating ─► price, or refuse

Adding a horse moves every price

102 features describe the field rather than any one runner — field size, the strength of the opposition, each horse’s rating relative to the others. They are recomputed on every change, which is the point of the tool.

You will fill in four things, not thirty

There are fifteen race conditions the model can read. You should not have to set fifteen dropdowns to price a race, so we measured which ones actually change the answer and hid the rest behind sensible defaults. Four inputs carry almost all of it.

InputWeightShown?
Prize fund14.74%Yes — first
Going4.40%Yes
Distance1.95%Yes
Race class1.37%Yes
Field size1.33%Implicit — it is how many horses you add
Track, handicap, surface, draw, days‑off, month, type2.02%Defaulted, editable under “more options”
Headgear, sex restriction, age band0.00%Not offered — the model does not use them

Prize fund is the single most informative condition by a factor of three, because it describes the quality of a race better than its class label does. It is the first field, and the one worth getting right.

Defaults are the median or most common value for the race shape you have already chosen — not a global average — and every default is visible and editable. Nothing is set behind your back. Dropdowns only ever offer combinations that occur in real races, so you cannot build a card that has never existed.

Nothing gets typed that can be inherited

Every horse you add arrives already filled in from its most recent run — trainer, headgear, age, days since it last ran, its usual code. You change what you want to change and ignore the rest. Three kinds of input, three different defaults:

Set once, for the race
Prize fund, going, distance, class. Defaults to the median for the shape of race you picked.
Inherited from the horse
Trainer, headgear, age, days off. Prefilled from its last actual run — change one to ask “what if it moved yards?”
Chosen per runner
Jockey and claim, weight or mark. Prefilled with the most likely, but this is the row you came to play with.

Age and days‑since‑run are computed from the race date you set, so moving the race moves them without you touching anything. Changing the trainer is a real question, not a curiosity — it is the same one the trainer‑move research asks.

Per‑runner inputs: who rides, and off what mark

Some things belong to the horse in this race rather than to the race: who is riding, what they claim, whether it is a handicap and off what weight or mark. Same treatment — we measured which of them the model actually reads.

InputWeightShown?
Jockey (and trainer / jockey pairing)12.47%Yes — second only to prize fund
Trainer0.97%Yes — comes with the horse, editable
Handicap or not0.57%Yes
Claim  /  allowance0.15%Yes, with the jockey
Handicap mark (BHA)0.011%Offered, but see below
Weight carried0.004%Offered, but see below

The jockey matters enormously and the weight barely registers. Nearly all of the jockey’s weight comes through the trainer / jockey pairing rather than the rider alone — the model has learned which yards put which riders up.

Why the handicap mark barely moves the price

A mark of 60 against 80 is twenty pounds. It ought to be enormous, and it is nearly nothing to the model — three features, 0.011% of its decision weight. That is worth explaining, because it is not a flaw.

Within a handicap the marks are tight: a median range of 14 lb across 322 real handicaps, with only 21.7% spanning twenty or more. And where the marks do spread, they rank the field weakly — within‑race rank correlation of +0.37 between mark and the model’s own view, against +0.75 between the model and the market.

The mark is uninformative on purpose. A handicapper’s job is to set marks so the field finishes together — the horse off 80 carries the extra weight precisely so it does not beat the one off 60. In a well‑framed handicap the mark has almost no predictive power by construction. So when you raise a mark here and the price hardly moves, the tool is agreeing with the handicapper, not ignoring you.

The question you actually want to ask is different. Not “what if this horse were rated 80?” but “what if this horse were ahead of its mark?” Those are separable here: set the mark and the weight independently and you can express a horse running off 60 that is really an 80 horse — well handicapped — which is the case worth pricing. Raising both together is the handicapper’s own adjustment and should, correctly, cancel out.

Swapping jockeys is the one to distrust. Good riders get good horses, so a model can credit the jockey with the quality of the mounts they usually get. Putting a top rider on a moderate horse here will flatter it more than reality would. The jockey tool exists to separate the rider from the mount; read a swap here as an upper bound, not an estimate.

When it will refuse

A sprinter entered at three miles on heavy ground should not get a confident price. The tool declines rather than extrapolating when:

With 108 features genuinely missing and 216 imputed, the refusal path matters more than the prediction path.

What this is not

A research tool, not a betting tool. The underlying model has no defensible betting edge on our own testing, and is anti‑correlated with market drift. It is built to answer “what would this field look like priced up?” — not to find bets. Prices for an invented race are never a prediction about a real one.
Figures measured 2026‑08‑17 from the frozen model files and this site’s published results (413 races, 3,637 runners). The without‑tissue row uses an existing no‑tissue model as a stand‑in; a direct test that removes the tissue from the live model itself is running and will replace it.