liveBook · Manning

Risk parity

As explained in Build a Robo-Advisor with Python (From Scratch)

Weighted risk parity is a portfolio-construction technique that assigns different optimization weights to instruments so aggregate risk contributions follow a specified asset-class structure.

Risk parity builds portfolios by balancing contributions to total portfolio risk rather than allocating capital equally. It addresses a practical trap: a 60/40 stock-bond portfolio can look diversified by dollars while stocks supply more than 117% of its risk contribution. Equal risk contributions occur near 20% stocks in the two-asset illustration. section 11.0 section 11.1.2

For weights w and covariance matrix Σ, asset i’s normalized contribution is w_i(Σw)_i/(wᵀΣw). General risk parity makes these contributions equal across assets. It can be found by minimizing ½wᵀΣw − γΣ_i log(w_i): the first-order condition makes each unnormalized contribution equal to γ. section 11.2.2

Common constructions differ by the covariance and contribution target:

  • Naive risk parity assumes a diagonal covariance matrix and sets weights proportional to inverse volatility, then rescales them to sum to one. section 11.2.1
  • General risk parity uses convex optimization when assets are correlated, while preserving equal instrument-level risk contributions. section 11.2.2
  • Weighted risk parity changes the log-weight penalties so several instruments can share a chosen top-level asset-class risk structure rather than letting asset-class risk depend on instrument counts. section 11.2.3

Eight instruments across three asset classes

If four equity, three bond, and one commodity instruments receive equal instrument-level risk contributions, equities receive 50% of total risk, bonds 3/8, and commodities 1/8. Assigning log-term weights of 1/4 to each equity, 1/3 to each bond, and 1 to commodities targets equal aggregate contributions from the three asset classes while balancing instruments within them. section 11.2.3

Listing 11.4 Weighted risk parity in Python
import yfinance as yf

tickers = ['VV', 'VB', 'VEA', 'VWO', 'AGG', 'BNDX', 'EMB', 'DJP']
rets = yf.download(tickers, start='2014-01-01', end='2021-12-31')
rets = rets['Adj Close'].pct_change().dropna(axis=0, how='any')[tickers]
sigma = np.matrix(rets.cov().values) * 252
                  
N = sigma.shape[0]                 
w = cp.Variable(N)               
gamma = np.concatenate((np.ones(4) / 4, np.ones(3) / 3, np.ones(1) / 1))
objective = cp.Minimize(0.5 * cp.quad_form(w, sigma) - (gamma @ cp.log(w)))         
constraints = []          
prob = cp.Problem(objective, constraints)
           
result = prob.solve()               
p = w.value
p_var = p @ sigma @ p               
risk_contribs = np.diag(p) @ sigma @ p / (p @ sigma @ p)        
risk_contribs

The Python listing estimates annualized covariance from ETF returns, solves the weighted convex program with CVXPY, and checks resulting risk contributions. section 11.2.3

Balanced risk does not set the portfolio’s desired return or volatility. In the two-asset case, the unlevered risk-parity allocation has about 4.7% volatility versus 10.3% for 60/40, so leverage can scale exposures toward a chosen risk level. Margin borrowing has interest costs and can trigger cash demands or liquidation after losses. section 11.3 section 11.3.1

How Build a Robo-Advisor with Python (From Scratch) covers it

How deep it goes
Derives equal-contribution conditions, formulates convex objectives, and implements naive, general, and weighted variants in Python.
Examples
Uses 60/40 stocks and bonds, a two-asset allocation, and eight ETFs grouped into equities, bonds, and commodities.
What it assumes
Assumes portfolio weights, covariance, volatility, and optimization basics while deriving the risk-contribution calculation and objective.
What you can do after
Apply it via CVXPY to estimate covariance, optimize weighted contributions, inspect risk contributions, and scale exposures with leverage.
How it connects
Connects covariance matrices, volatility, mean-variance optimization, convex optimization, leverage, and hierarchical risk parity.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Build a Robo-Advisor with Python (From Scratch). The section links point to the parts of the book it draws on.