2nd Place Pricer

how the place / 2nd prices are computed

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:

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:

p_second ≈ max(0, 1/place_odds − 1/win_odds)
It is only a rough approximation: the two markets are priced independently, carry different overrounds and different liquidity, so the subtraction is noisy and can even go negative. The app still shows it (“2nd crude”) so you can see how far the principled models move away from it.

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”:

P(i is 2nd) = Σj≠i p_j · p_i / (1 − p_j)

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:

select i ∝ p_iλ (λ = 1 → Harville exactly; λ < 1 → longshots place more)

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-friendlinessOrder
most → leastHenery > Stern > Bacon-Shone > Harville
At greyhound fields (≈6 runners) and even horse fields (8–15), the methods differ by only about 1–2% on place probabilities, so Harville analytically is perfectly defensible and fast. Bacon-Shone is the cheapest way to add a visible longshot correction; Henery and Stern are more compute for marginal payoff at these field sizes. The most useful column is still the live Exchange place market — the models tell you where it looks rich or cheap.

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.