Portfolio Optimization: Markowitz to Machine Learning
Module: Fintech AI | Difficulty: Advanced
Mean-Variance Optimization
Risk Parity
Black-Litterman
Kelly Criterion
import numpy as np
from scipy.optimize import minimize
class PortfolioOptimizer:
def __init__(self, returns, cov_matrix, risk_aversion=1.0):
self.returns = returns; self.cov = cov_matrix; self.lam = risk_aversion
def mean_variance(self):
n = len(self.returns)
def neg_utility(w):
ret = w @ self.returns
risk = w @ self.cov @ w
return -(ret - self.lam/2 * risk)
constraints = [{'type': 'eq', 'fun': lambda w: np.sum(w) - 1}]
bounds = [(0, 1) for _ in range(n)]
w0 = np.ones(n) / n
result = minimize(neg_utility, w0, bounds=bounds, constraints=constraints)
return result.x
def risk_parity(self):
n = len(self.returns)
def risk_budget_objective(w):
portfolio_risk = np.sqrt(w @ self.cov @ w)
risk_contributions = w * (self.cov @ w) / portfolio_risk
target = portfolio_risk / n
return np.sum((risk_contributions - target)**2)
constraints = [{'type': 'eq', 'fun': lambda w: np.sum(w) - 1}]
w0 = np.ones(n) / n
result = minimize(risk_budget_objective, w0, constraints=constraints)
return result.x
Research Insight: Markowitz optimization is notoriously sensitive to input estimates. Black-Litterman addresses this by combining market equilibrium with investor views, producing more stable allocations. Machine learning approaches improve estimation of expected returns and covariances.