Finding an edge is half the problem. The other half is how much to bet on it. Bet too little and you leave money on the table; bet too much and a run of bad luck wipes you out even though every bet was favourable.
Where it comes from in the guide
Five Rings. You and the interviewer bet on opposite sides of a game at even odds. You start with $100. How much do you bet? What if you can play infinitely many rounds?
For a single round there is no right answer: the interviewer wants to see you reason about risk relative to your wealth. For many rounds there is: the Kelly criterion.
The formula
Suppose each bet wins a fraction of the stake with probability and loses the stake with probability . Betting a fraction of wealth each time, wealth after bets is . Maximise the expected log growth per bet:
More generally, if a loss costs a fraction of the stake, . If , you have no edge: don’t bet (or take the other side).
Why logs? Wealth compounds multiplicatively, so the long-run growth rate is the average of . Maximising it maximises long-run wealth with probability approaching 1.
Applying it to the sock game
The guide’s game: draw socks from 3 labelled pairs, win if every pair you draw is labelled at most 1 apart. Count the pairings directly: of the 15 equally likely ways to pair up six socks, only 5 work (33, two ways of 23, two ways of 33). So the game wins with probability 1/3.
Kelly in practice
- Fractional Kelly. Real edges are estimated, not known. Overestimating your edge pushes you past Kelly, where growth collapses. Most practitioners bet half Kelly or less: it keeps about 75% of the growth with much smaller drawdowns.
- Continuous version. For a strategy with expected excess return and volatility , the Kelly leverage is , the same ratio that appears in mean–variance optimisation.
- Many bets at once. With correlated positions, Kelly becomes a portfolio problem (), and correlations matter as much as edges.
In code
import numpy as np
rng = np.random.default_rng(16)
def kelly(p, b, a=1.0):
return p / a - (1 - p) / b
print(kelly(0.6, 1)) # 0.2
print(kelly(2/3, 1)) # 1/3: betting against the 3-pair sock game
def median_growth(f, p=0.6, b=1, n=250, paths=20_000):
wins = rng.binomial(n, p, paths)
logw = wins * np.log1p(b * f) + (n - wins) * np.log1p(-f)
return np.exp(np.median(logw))
for f in (0.1, 0.2, 0.4): # half Kelly, Kelly, twice Kelly
print(f, round(median_growth(f), 2))
Check yourself
A bet pays 2 : 1 (b = 2) and wins 40% of the time. What fraction of wealth does Kelly bet?