From win odds to place & “exactly 2nd” prices
The app reads each runner's Win and Place prices from the Matchbook exchange. The Win prices tell you each runner's chance of winning; turning that into the chance of placing (or finishing exactly 2nd) needs a model of how a race plays out. This page explains the models the app lets you compare — and why they disagree.
Step 1 — de-overround the Win market
Bookmakers' and exchanges' implied probabilities sum to more than 100% (the
“overround”). We first strip that out so the win probabilities pi
sum to exactly 1. Three methods are available:
- Proportional — divide each
1/oddsby the booksum. Simplest; spreads the vig evenly. - Power — find an exponent
αwithΣ (1/oddsi)α = 1. Takes more vig from longshots. - Shin — models a fraction of insider money; a principled favourite-longshot correction.
Step 2a — the crude shortcut what the old tool did
The simplest “exactly 2nd” estimate is just P(place) − P(win) taken
straight from the two markets:
Step 2b — Harville 1973 · baseline
Harville assumes runners are removed one at a time, each step proportional to win
probability among those left (a Gumbel / exponential performance model). The chance
runner i finishes 2nd is “someone else wins, then i
wins the rest”:
Place (top-k) probabilities come from the same conditioning logic over the first k positions. It is closed-form and exact for the model, but carries the IIA bias: it overstates favourites' chance of placing and understates longshots'.
Bacon-Shone 1992 · the pragmatic fix
Rather than commit to a new distribution, raise the remaining win probabilities to a
power λ before renormalising at each elimination step:
One extra parameter on top of code you already have, fitted from historical results. The cheapest correction and surprisingly effective — the app's default is λ = 0.85.
Plackett-Luce Monte-Carlo
The general name for the same sequential-sampling model behind Harville. Here it is computed by simulation: sample many full finishing orders (Gumbel-perturbed log win probabilities) and count how often each runner lands top-k or exactly 2nd. In expectation it matches Harville — it is a useful sanity check and scales cleanly to big fields.
Henery 1981 · Gaussian
Each runner has a latent performance drawn from a normal distribution; the highest score wins. Place probabilities follow from multivariate-normal comparisons. Removing a strong runner shifts the remaining field differently than removing a weak one, so it corrects the IIA bias naturally. The app calibrates each runner's mean so the simulated win probabilities match the de-overrounded market, then reads off place / 2nd frequencies.
Stern 1990 · Gamma
Performances follow a gamma distribution with a shape parameter. It sits between Harville and Henery — in fact Harville is the limiting case as the shape → ∞. A finite shape lifts longshots' place chances and trims favourites', closer to empirical results. Calibrated by simulation like Henery (app default shape = 4).
Davidson-Luce & ties not included
Davidson-Luce extends Plackett-Luce with an explicit dead-heat parameter. The app doesn't model ties (dead heats are rare and handled by the exchange's own rules), so this is left out by choice.
Which to trust?
| Longshot-friendliness | Order |
|---|---|
| most → least | Henery > Stern > Bacon-Shone > Harville |
Implementation lives in app/place_models.py (pure numpy/scipy, unit-tested
against hand-worked Harville values). The de-overround method, Bacon-Shone power and
Stern shape are all parameters.