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 winningq = 1 - p= probability of losingb= 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)andhalf_kelly(win_prob, win_loss_ratio)max_drawdown(portfolio_values)— returns the maximum drawdown (as a positive fraction) from a list of portfolio valuesvol_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.