Bet Better BET BETTER PRO

R at Bet Better › R for Betting-Market Data

Chapter 1. Prices and probabilities

20 October 2026. Edward Glush. Code run in R 4.4.1 against the live open data on that day.

A betting price is a probability in disguise, with the bookmaker's cut mixed in. This chapter shows how to pull the two apart with a few lines of base R. No packages are needed.

Data and licence. No download is needed for this chapter. The prices are typed in by hand. The same steps are applied to a whole open file in chapter 3 (the Margin Index) and chapter 5 (the price movement dataset, CC BY 4.0).

1.1 What a decimal price says

Decimal odds are the most common format outside North America. A price of 2.10 means a one-dollar bet returns 2.10 dollars in total if it wins. That is the stake back plus 1.10 profit.

Flip the price over and you get a probability. One divided by 2.10 is about 0.476. In plain words: the price says the outcome happens about 47.6 times in 100. This number is called the implied probability.

We will use one market for most of this book: a soccer match with three outcomes. Home win at 2.10, draw at 3.40, away win at 3.50.

odds <- c(home = 2.10, draw = 3.40, away = 3.50)
implied <- 1 / odds
round(implied, 4)
##   home   draw   away 
## 0.4762 0.2941 0.2857 

1.2 The overround

In a fair market the three probabilities would add to exactly 1. One of the outcomes must happen. Here they add to more than 1.

booksum <- sum(implied)
round(booksum, 4)
overround <- booksum - 1
round(100 * overround, 2)
## [1] 1.056
## [1] 5.6

The extra 5.6 per cent is the overround. It is how the bookmaker builds its cut into the prices. Every outcome is priced a little shorter than a fair price would be. So the probabilities are a little too high, and together they add to more than 100 per cent.

1.3 Margin: the share of each dollar the bookmaker keeps

The overround is easy to compute, but it is not quite the share of money the bookmaker keeps. Picture someone who spreads 100 dollars across all three outcomes, sized so they get the same return whatever happens. They get back 100 divided by the booksum.

stake <- 100
payout <- stake / booksum
round(payout, 2)
margin <- 1 - 1 / booksum
round(100 * margin, 2)
## [1] 94.69
## [1] 5.31

They get back 94.69 dollars. The missing 5.31 dollars is the margin, also called the hold or the vig. Both numbers are in common use. The overround is 5.6 per cent and the margin is 5.31 per cent, for the same three prices. When you read a number from someone else, check which one they mean.

A familiar two-way example is a line priced 1.91 on both sides. That is about -110 in American odds.

two <- c(yes = 1.91, no = 1.91)
round(100 * (sum(1 / two) - 1), 2)      # overround
round(100 * (1 - 1 / sum(1 / two)), 2)  # margin
## [1] 4.71
## [1] 4.5

1.4 Fair probabilities and fair odds

To get a fair probability, the simplest move is to divide each implied probability by the booksum. The three numbers then add to 1. Flip them back over and you have fair odds: the price with the bookmaker's cut taken out.

fair <- implied / booksum
round(fair, 4)
sum(fair)
fair_odds <- 1 / fair
round(fair_odds, 2)
##   home   draw   away 
## 0.4509 0.2785 0.2706 
## [1] 1
## home draw away 
## 2.22 3.59 3.70 

This is called the proportional method. It assumes the cut is spread across the outcomes in proportion to their size. That is a fair first guess, but real bookmakers often load more of the cut onto the long shots. Chapter 2 compares four ways to remove the margin, and shows how much the answer changes.

1.5 American and fractional odds

North American books quote American odds. A positive number is the profit on a 100 stake. A negative number is the stake needed to win 100. UK books often quote fractions, such as 11/10. All of these convert to decimal in one line, and from there to a probability.

american_to_decimal <- function(a) ifelse(a > 0, 1 + a / 100, 1 + 100 / abs(a))
american_to_decimal(c(-110, +150, -250))

decimal_to_american <- function(d) ifelse(d >= 2, round(100 * (d - 1)), round(-100 / (d - 1)))
decimal_to_american(c(1.91, 2.50, 1.40))

fractional_to_decimal <- function(num, den) 1 + num / den
fractional_to_decimal(c(11, 5, 2), c(10, 2, 5))
## [1] 1.909091 2.500000 1.400000
## [1] -110  150 -250
## [1] 2.1 3.5 1.4

Note that 1.91 comes back as -110. The true decimal for -110 is 1.909, so 1.91 is that number rounded. Rounding is common in published prices, and it can move a small margin by a tenth of a point. Keep the unrounded figure if you have it.

1.6 One function for a whole market

It helps to wrap the steps in a function that takes a named vector of prices and returns one row per outcome. We will reuse this idea through the book.

market_summary <- function(odds) {
  implied <- 1 / odds
  booksum <- sum(implied)
  data.frame(outcome = names(odds), odds = odds,
             implied = round(implied, 4),
             fair = round(implied / booksum, 4),
             fair_odds = round(booksum / implied, 2),
             row.names = NULL)
}
market_summary(odds)
##   outcome odds implied   fair fair_odds
## 1    home  2.1  0.4762 0.4509      2.22
## 2    draw  3.4  0.2941 0.2785      3.59
## 3    away  3.5  0.2857 0.2706      3.70

The function returns a data frame, so you can bind many markets together with rbind() and then group them, which is exactly what chapter 3 does at scale.

1.7 Things to watch

  • A market must be complete. If you leave out one outcome (the draw, say) the booksum will look too small and the margin will look negative.
  • Prices from different bookmakers should not be mixed inside one market when you measure a margin. Each book sets its own cut.
  • Implied probabilities are the bookmaker's view plus its cut. They are not the truth. Chapter 4 checks how close they come to what actually happens.
  • Small prices hide big margins. A 1.05 favourite looks safe, but a small change in its price is a big change in the cut.

Try it yourself

  • Take a two-way market at 1.80 and 2.05. Work out the overround, the margin and both fair prices.
  • Write a function that takes a vector of American odds and returns the margin directly.
  • Find a price board with a four-way or five-way market. Does the margin grow with the number of outcomes?

Data licensed CC BY 4.0, free to reuse with a credit. Model estimates, not advice. 18+. If gambling is causing you harm: gamblinghelponline.org.au.

Get tomorrow's free pick by email

Free. One email a day, tops. Unsubscribe in one tap.

18+ only. Please gamble responsibly.