Using the Kelly Criterion for Betting

Jan. 29, 2021 by SportsBettingQuant

When you place a bet on a certain outcome with a bookmaker or betting exchange you might ask yourself how much you should stake or risk and what is the optimal bet size.

There is the possibility that you risk too little and work with too small stakes. When you lose your bet you don't lose much money which is good. On the other hand, if you win, you also don't win much because your stakes are too low. In the end you spend some time and effort with sports betting but it doesn't pay off as your account doesn't improve much.

The other is extreme is that you risk to much and place too large bets. Taking large risk is great when you win and it pays off. The problem is losing: A few lost bets can completely destroy your bankroll when you work with extremely large stakes.

Now that we understand the extreme scenarios, betting too little and betting too much, the question is: What is the optimal size for a bet?

Optimal staking has been a field of study in the area of probability theory for quite some time. In 1956 a researcher at Bell Labs named J. L. Kelly created the formula that would be known as Kelly criterion.

Definition of the Kelly Criterion

The Kelly Criterion tells you how much of your bankroll you should risk when betting on a certain outcome. The size of the bet depends on the offered odds and the probability of the outcome. The formula of the Kelly criterion defines how much of your bankroll you should bet:

\begin{equation*} f = \frac{p (b + 1) - 1}{b}\end{equation*}

with:
p: probability of winning the bet
b = odds - 1

To give you an example: Let's assume that a bookmaker offers you to place a back bet on a certain outcome with decimal odds of 2.0 whilst the probability of the outcome is 60%.

\begin{equation*} f = \frac{p (b + 1) - 1}{b} = \frac{0.6 * (1 + 1) -1}{1} = 0.2\end{equation*}

This means that the recommended bet size for this kind of bet is 20% of your bankroll.

There are also staking variations that only use a fraction of the Kelly criterion. Popular example are half Kelly (where only half of the Kelly stake is used) or quarter Kelly (using 25% of the Kelly stake).

Calculator for the Kelly Criterion

With the following tool you can easily calculate the optimal staking for your bet. You simply need to specify the odds as well as the probability for the event:

 Odds (Odds in decimal format, e.g. 1.6, 2.0, 10.5, etc) Probability Probability between 0.0 and 1.0 Kelly Bet Stake as percentage of bankroll

As a result you will get the fraction of your bankroll (percentage) that should be used for your bet.

Instead of relying on online tools to calculate the Kelly stake you can easily use a spreadsheet software or a programming language of your choice to implement the formula and calculate stakes for  various scenarios.

Using the Kelly Criterion in Python

Looking at the definition of a Kelly bet for an event with two outcomes we can use the following Python function to calculate the Kelly bet:

def kelly_criterion(odds: float, p: float) -> float:
b = odds - 1.0
return (p*(b+1)-1)/b

It is basically a function that depends on two arguments: the offered odds and the probabilities. You can easily create a heat map with the odds on the x axis and the probability on the y axis which looks like the following:

The color scheme goes from red to blue. Red areas are the ones that you should not bet on, it is where the offered odds are lower than the probability. Red color means zero staking. Blue is the other extreme where you would bet almost the whole bankroll.

Using the Kelly Criterion in a Spreadsheet Software

You can also use spreadsheet software such as Microsoft Excel or LibreOffice Calc to calculate the Kelly bet. In LibreOffice Calc you can simply use the following formula and build your own Kelly Criterion calculator tool:

Comparing and Simulating Different Staking Options

Now that we have covered the basics of the Kelly Criterion you might ask yourself why it is worth using Kelly bets. There is a mathematical proof that shows that the Kelly criterion is superior compared to other staking plans which you can follow along on the Wikipedia page. However, I will use a more empirical approach to illustrate that the Kelly Criterion is better than other staking plans.

First, let's have a look at a couple of staking options that are most common in the area of sports betting. We will compare the Kelly Criterion with the following two staking plans:

Flat Staking

When you use flat staking you simply risk a fix amount per bet. Let's say 1 unit per bet. It does not rely depend on the size of your bankroll. Of course you should be able to sustain a longer period of drawdown but your bet size is not re-evaluated on a per bet basis. For most of the betting strategies that I present here flat staking is used in the backtests.

Proportional Staking

When following a proportional staking approach your bet size is a certain percentage of you bankroll, let's say 1% as an example. For every bet you need to take into account your bankroll and re-calculate the bet size. If your account is at 100 you would need to risk 1 unit with a 1% proportional stake. However, if your account shrinks to 80 units you would only risk 0.8 units per bet.

Simulating Betting Accounts

I will use a simple Python script to simulate how betting accounts evolve following different staking plans. First I will generate some random odds using a normal distribution with mean 2.0 and stdev 0.1:

# random odds
np.random.seed(0)
mu, sigma = 2.0, 0.1
s = np.random.normal(mu, sigma, 1000)

The 1000 odds in my example are in the range between 1.70 and 2.28. I assume that the true probability of those events is always 0.5 and hence there is a 50% chance for win and lose at every bet. I will then simulate a portfolio where different staking options are used: Kelly bet, proportional of the bank and constant staking. The following functions returns the account balance after the 1000 for each of the staking options:

def simulate_balance():
df = pd.DataFrame({"odds": s})
df["proba"] = 0.5
df["win_lose"] = np.random.choice((True, False), len(df))
df["kelly_criterion"] = df.apply(lambda x: kelly_criterion(x["odds"], x["proba"]), axis=1)
df["kelly_profit"] = df.apply(lambda x: kelly_profit(x["odds"], x["proba"], x["win_lose"]), axis=1)
df["kelly_balance"] = 1.0
proportional_stake = np.mean([stake for stake in df["kelly_criterion"].values if stake>0])
df["proportional_profit"] = df.apply(lambda x: get_profit(x["odds"], proportional_stake, x["win_lose"]), axis=1)
constant_stake = proportional_stake
df["constant_profit"] = df.apply(lambda x: get_profit(x["odds"], constant_stake, x["win_lose"]), axis=1)
for index, row in df.iterrows():
if index >= 1:
kelly_balance = df.iloc[index-1]["kelly_balance"] * (1+row["kelly_profit"])
proportional_balance = df.iloc[index-1]["proportional_balance"] * (1+row["proportional_profit"])
else:
kelly_balance = 1+row["kelly_profit"]
proportional_balance = 1+row["proportional_profit"]
df.ix[index, "kelly_balance"] = kelly_balance
df.ix[index, "proportional_balance"] = proportional_balance
return kelly_balance, proportional_balance, 1.0 + df.constant_profit.sum()

I can now run this simulation multiple times to aggregate some statistics. I will run it 100 times and calculate the mean value for each group of staking:

Staking Plan Average Balance after 1.000 Bets
Kelly Criterion 2.65
Proportional Staking 1.70
Flat Staking 1.56

Remember that the starting balance was 1.0 and that bets were only placed when the odds were larger than 2.0 as we assumed a 50% chance of winning. From this data it seems that Kelly criterion performs better than proportional staking and flat staking.