Lesson 15 of 15

Kelly Criterion Sizing

Kelly Criterion

The Kelly Criterion is a formula for determining the optimal fraction of capital to wager on a bet (or trade) to maximize the long-term growth rate of wealth.

Formula

Given:

  • p = probability of winning
  • q = 1 - p = probability of losing
  • b = win/loss ratio (how much you win per unit risked)
kelly_fraction = p - q / b

Interpretation

  • Positive Kelly: bet this fraction of your capital
  • Zero or negative: do not take the bet

Half-Kelly

In practice, many traders use "half-Kelly" — betting half the Kelly fraction — to reduce volatility while sacrificing some growth:

half_kelly = kelly_fraction / 2

Example

If you win 60% of the time (p = 0.6) with a 2:1 payout (b = 2):

kelly = 0.6 - 0.4 / 2 = 0.6 - 0.2 = 0.4

Bet 40% of your capital on each trade.

Drawdown Limits

A maximum drawdown limit caps how much the portfolio can fall from its peak before the strategy stops trading. The drawdown at time t is:

drawdown(t) = (peak - value(t)) / peak

If drawdown exceeds the limit, the position size is set to zero. This is a critical risk control that prevents catastrophic losses — even a strategy with a positive Kelly fraction can experience devastating drawdowns.

Volatility Targeting

Volatility targeting scales position size so the portfolio maintains a constant annualized volatility target. Given recent realized volatility σ_realized and a target σ_target:

vol_scale = sigma_target / sigma_realized

The Kelly fraction (or any position size) is then multiplied by vol_scale. When the market is calm, you trade larger; when volatile, you reduce exposure. This is the most common professional risk management technique and is used by virtually all systematic funds.

Task

Implement:

  • kelly_fraction(win_prob, win_loss_ratio) and half_kelly(win_prob, win_loss_ratio)
  • max_drawdown(portfolio_values) — returns the maximum drawdown (as a positive fraction) from a list of portfolio values
  • vol_target_scale(recent_returns, target_vol) — returns the scaling factor given a list of recent daily returns and an annualized target volatility. Annualize daily std by multiplying by sqrt(252). If realized vol is 0, return 1.0.
Python runtime loading...
Loading...
Click "Run" to execute your code.