Portfolio Optimization: From Markowitz to Modern Risk Parity
Portfolio Optimization: From Markowitz to Modern Risk Parity
You've got great signals. Now how do you size your positions? Portfolio construction is where most quants leave alpha on the table.
The Evolution
1952: Markowitz Mean-Variance
The original. Maximize expected return for a given level of risk. Beautiful in theory, terrible in practice — it's extremely sensitive to estimated expected returns.
1990s: Black-Litterman
Combines market equilibrium returns with investor views. More stable than raw Markowitz, but still requires return forecasts.
2000s: Risk Parity
Don't forecast returns at all. Instead, allocate risk equally across assets. Simple, robust, and surprisingly effective.
2020s: Hierarchical Risk Parity (HRP)
Uses machine learning (hierarchical clustering) to build more robust portfolios that avoid the pitfalls of traditional covariance inversion.
Implementing Risk Parity
import numpy as np
def risk_parity_weights(cov_matrix: np.ndarray) -> np.ndarray:
"""Equal risk contribution portfolio."""
n = cov_matrix.shape[0]
# Start with inverse-volatility weights
vols = np.sqrt(np.diag(cov_matrix))
weights = (1 / vols) / np.sum(1 / vols)
# Iterate to equalize risk contributions
for _ in range(100):
port_vol = np.sqrt(weights @ cov_matrix @ weights)
marginal_risk = cov_matrix @ weights / port_vol
risk_contrib = weights * marginal_risk
target = port_vol / n
weights = weights * (target / risk_contrib)
weights /= weights.sum()
return weights
What Wins on AlphaNova
Our top performers typically use:
- Volatility targeting — Scale positions so portfolio vol stays at ~10-15%
- Position limits — No single stock exceeds 5% of the portfolio
- Sector neutrality — Net exposure to each sector is near zero