Documentation / Guides
Prices and price movement
Fractional, decimal, opening, touched, and what source tells you.
Prices are the most useful thing in this archive and the easiest to misread. Four fields, one derived summary, and one coverage limit worth knowing before you build on any of it.
The four fields on a runner
| Field | Example | What it is |
|---|---|---|
sp | "10/3" |
Starting price, fractional, exactly as published. |
sp_decimal | 4.3333 |
The same price as a decimal. Computed once at load so you are not parsing fractions per row. |
implied | 0.2308 |
One over the decimal price. |
market_position | 1 |
Rank by price, one being shortest. Ties share a rank. |
implied does not sum to one
This is the thing people get wrong. Add implied across a field and you get the
book percentage, not 1.0.
0.2308 + 0.1667 + 0.1250 + ... = 1.2185 # a 121.85% book
The excess is the margin. It is real and it is the reason backing everything loses money.
If you want probabilities that sum to one, the statistics endpoints already have them:
expected is implied normalised per race. That is what A/E is computed
against, and it is why A/E of 1.00 means "as often as the market said" rather than "as often as
the book implied".
book_percentage
On the race, from /v1/races/{race_id}/market. A hundred would be a fair book.
In our archive it averages about 117 in fields of two to seven and about 133 in sixteen or more. That spread matters more than the average. A strategy that looks marginally profitable in small fields can be hopeless in big ones with nothing else changing. Overround has it sliced by course, class and year.
Price movement, and its limit
price_path carries the opening price, any prices touched, the drift, and a
source field naming which kind of history you have.
"price_path": {
"opening": "5/1",
"opening_decimal": 6,
"touched": ["4/1"],
"sp": "10/3",
"drift": -0.2778,
"direction": "shortened",
"source": "movements"
}
source | Means |
|---|---|
movements | An opening price and any touched prices. The common case where movement exists. |
full_history | A complete price series. Rare. |
starting_price_only | No movement was published. The starting price is all there is. |
Read source rather than inferring from a null opening price.
The two are different claims: one says nothing was published, the other says we do not know.
The limit: price movement is British and Irish. Britain carries an opening price on about 59% of runners and Ireland on about 52%. France, America, South Africa and Germany carry essentially none. Any model using movement works on two countries, and it is better to design for that than discover it.
And it is opening to starting price, not a series. A horse that shortened and drifted back looks like it never moved.
favourite is ours, not the source's
The source leaves both favourite and market_position empty on a
settled race, so we derive them from the prices: ranked on decimal price, shortest first.
Joint favourites are all flagged and share rank one, which slightly inflates
favourite counts in the races where it happens. Picking one arbitrarily would be worse.
Tote is a separate thing
/v1/races/{race_id}/dividends returns tote returns to a one unit stake,
normalised into numbers with a currency alongside. Tote and starting price settle differently
and the gap is occasionally large. Most jurisdictions outside Britain and Ireland publish no
tote return, and the endpoint says so rather than erroring.
What we do not have
No bookmaker odds comparison, no exchange prices, no in-running. Starting price, an opening price where one was published, and the tote. We are not a price aggregator and will not become one.