Mean-Variance Position Sizing
Size positions optimally as μ/σ² scaled by risk aversion — Markowitz meets dynamic trading.
The Intuition
Mean-Variance Optimization, introduced by Harry Markowitz (1952), is the mathematical foundation of modern portfolio theory. Applied as a dynamic single-asset strategy, it determines the theoretically optimal position size at each point in time given estimates of expected return (mu) and variance (sigma²). Unlike binary long/short signals, it produces a continuously variable position that shrinks as uncertainty increases and grows as the risk-adjusted return improves.
The Merton (1969) intertemporal consumption model shows that the optimal risky asset allocation for a CRRA investor is exactly w* = mu / (sigma² × risk_aversion). This is the formula we implement. With risk_aversion = 1, the position is the unconstrained Kelly fraction — the growth-optimal bet size. Higher risk aversion shrinks the position, acting as a conservative multiplier on the Kelly fraction.
The key advantage over a binary signal: position sizing is proportional to the signal strength. When mu is large relative to sigma², the strategy takes a large long position. When mu and sigma² are both large (high-momentum but also high-volatility), the position is moderated by the risk. This volatility-targeting property means the strategy naturally de-risks during volatile periods — unlike fixed-size strategies that maintain full exposure through market turbulence.
Key assumptions: (1) The rolling estimates of mu and sigma² are unbiased predictors of future return and variance. In practice, expected return estimation is notoriously noisy — the signal-to-noise ratio in mu estimates is very low at daily to weekly horizons. (2) Returns are approximately normally distributed — fat tails mean the Gaussian variance understates true risk. (3) The position is continuously rebalanced — in reality, transaction costs create a "no-trade zone" around the optimal position.
The strategy's practical failure mode is estimation error in mu: rolling sample means of returns are extremely noisy. A 60-day rolling mean of daily returns has a standard error of approximately sigma / sqrt(60), which is typically larger than the true expected daily return. This noise creates excessive position turnover and whipsaw losses. Practitioners often use shrinkage estimators (e.g., James-Stein) or factor-based expected return models to reduce estimation error.
The Math
Read this as a compact model summary: what the signal sees, what it ignores, and where fragility can creep in.
mu(t) = mean(r[t-n:t]) × 252 [annualised return] sigma2(t) = var(r[t-n:t]) × 252 [annualised variance] w*(t) = mu(t) / (sigma2(t) × risk_aversion) Position(t) = clip(w*(t), -1, +1)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| window | int | 60 | Rolling window for estimating μ and σ |
| risk_aversion | float | 1.0 | Risk aversion coefficient (higher = smaller positions) |
Source Code
def run(ticker: str, start: str, end: str, **params) -> dict:
window = int(params.get("window", 60))
risk_aversion = float(params.get("risk_aversion", 1.0))
df = fetch_ohlcv(ticker, start, end)
log_ret = np.log(df["Close"] / df["Close"].shift(1))
mu = log_ret.rolling(window).mean() * 252
sigma2 = (log_ret.rolling(window).std() ** 2) * 252
raw_pos = mu / (sigma2.replace(0, np.nan) * risk_aversion)
pos = raw_pos.clip(-1.0, 1.0).fillna(0.0)
return run_backtest(df, pos, ticker=ticker, start=start, end=end,
strategy=METADATA["slug"],
params={"window": window, "risk_aversion": risk_aversion})
Further Reading
- Markowitz, H. (1952). Portfolio Selection. Journal of Finance, 7(1), 77–91.
- Merton, R. (1969). Lifetime Portfolio Selection Under Uncertainty: The Continuous-Time Case. Review of Economics and Statistics, 51(3), 247–257.
- Grinold, R. & Kahn, R. (2000). Active Portfolio Management, 2nd ed. McGraw-Hill.
- Chan, E. (2013). Algorithmic Trading, Ch. 5. Wiley.
When It Works / When It Fails
- Instruments with stable estimated mean and variance
- Portfolios where risk-budgeting adds measurable value
- When Gaussian return assumptions approximately hold
- High-uncertainty environments with noisy mean estimates
- Fat-tailed return distributions (Gaussian assumption violated)
- Regime shifts where parameters move faster than the window