Advanced Portfolio Construction Techniques › Risk Parity and Risk Budgeting
Quantitative FinanceAll chapters Advanced Portfolio Construction Techniques › Risk Parity and Risk BudgetingOne section · Sections in this chapter6 / 11 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Risk parity represents a fundamentally different approach to portfolio construction. Rather than optimizing expected return per unit of risk, risk parity allocates capital so that each asset contributes equally to total portfolio risk. This approach gained prominence after the 2008 financial crisis, when traditional 60/40 stock-bond portfolios suffered large losses due to their concentration of risk in equities. Many investors holding 60% stocks and 40% bonds believed they were diversified, only to discover that over 90% of their portfolio risk came from the equity allocation.
Risk Contribution
To understand risk parity, we first need to define precisely what we mean by an asset's contribution to portfolio risk. Intuitively, we want to answer the question: if we slightly increase our position in Asset X, how much will our portfolio volatility change? This marginal contribution to risk, combined with the current position size, tells us how much each asset contributes to the total.
The total portfolio volatility can be decomposed into contributions from each asset:
where:
- : total portfolio volatility (standard deviation)
- : number of assets
- : weight of asset
- : risk contribution of asset
This decomposition follows from Euler's theorem for homogeneous functions: portfolio volatility is homogeneous of degree one in the weights, meaning if we scale all weights by a factor , volatility also scales by . Euler's theorem then guarantees that volatility can be exactly decomposed into the sum of each weight times its marginal contribution.
The marginal contribution to risk (MCR) for asset is derived from the portfolio volatility derivative using the chain rule:
where:
- : portfolio volatility
- : vector of portfolio weights
- : covariance matrix of asset returns
This formula has an intuitive interpretation. The term is a vector whose -th element represents the covariance between asset and the overall portfolio. An asset's marginal contribution to risk depends on its own volatility and on how it comoves with the portfolio as a whole. An asset with high own volatility but negative correlation with other holdings might reduce portfolio risk at the margin.
For a single asset , the MCR is the -th element:
where:
- : marginal contribution to risk of asset
- : portfolio volatility
- : covariance matrix of asset returns
- : vector of portfolio weights
- : the -th element of the vector product
The total risk contribution (RC) for asset combines the position size with the marginal contribution:
where:
- : total risk contribution of asset
- : weight of asset
- : marginal contribution to risk of asset
- : covariance matrix of asset returns
- : vector of portfolio weights
- : the -th element of the vector product
- : portfolio volatility
By construction, the risk contributions sum to total portfolio volatility: . This additive decomposition allows us to express what fraction of portfolio risk comes from each asset, which allows meaningful comparisons across holdings.
def risk_contribution(w, cov):
"""
Calculate risk contributions for each asset.
Returns:
--------
rc : array
Absolute risk contribution for each asset
rc_pct : array
Percentage risk contribution for each asset
"""
port_var = w @ cov @ w
port_vol = np.sqrt(port_var)
# Marginal contribution to risk
mcr = cov @ w / port_vol
# Total risk contribution
rc = w * mcr
rc_pct = rc / port_vol
return rc, rc_pct
# Analyze risk contribution of equal-weight portfolio
w_equal = np.ones(5) / 5
rc, rc_pct = risk_contribution(w_equal, true_cov)Risk Contribution Analysis: Equal-Weight Portfolio ============================================================ Portfolio volatility: 13.91% Asset Weight Vol Risk Contrib % of Total ------------------------------------------------------------ Asset A 20.00% 15.00% 0.0172 12.34% Asset B 20.00% 20.00% 0.0294 21.17% Asset C 20.00% 25.00% 0.0378 27.18% Asset D 20.00% 18.00% 0.0215 15.48% Asset E 20.00% 22.00% 0.0331 23.83% Total 100.00% - 0.1391 100.00%
Even with equal capital weights, the risk contributions are far from equal. Higher-volatility assets contribute disproportionately to portfolio risk. Asset C, with 25% volatility, contributes roughly 25% of portfolio risk despite having only 20% of capital. Meanwhile, Asset A, with 15% volatility, contributes only about 15% of risk. This mismatch between capital allocation and risk allocation is precisely what risk parity seeks to address.

The Risk Parity Portfolio
A risk parity portfolio equalizes risk contributions across all assets. Rather than asking 'how should you allocate your capital?', risk parity asks 'how should you allocate your risk budget?' The answer is to find weights such that:
where:
- : risk contribution of asset
- : risk contribution of asset
or equivalently, expressed in terms of weights and marginal contributions:
where:
- : weights of assets and
- : the -th element of the covariance-weight product (proportional to marginal risk)
This is a nonlinear system of equations because the marginal contributions themselves depend on the weights. There is no closed-form solution in general, so we must solve numerically. The optimization finds weights that minimize the dispersion of risk contributions, subject to the constraint that weights sum to one.
def risk_parity_portfolio(cov, risk_budget=None):
"""
Compute risk parity portfolio weights.
Parameters:
-----------
cov : array
Covariance matrix
risk_budget : array, optional
Target risk allocation (default: equal risk)
Returns:
--------
w : array
Portfolio weights
"""
n = cov.shape[0]
if risk_budget is None:
risk_budget = np.ones(n) / n
def objective(w):
# Minimize sum of squared deviations from target risk contributions
port_var = w @ cov @ w
port_vol = np.sqrt(port_var)
# Risk contributions
rc = w * (cov @ w) / port_vol
rc_pct = rc / port_vol
# Squared error from target
return np.sum((rc_pct - risk_budget) ** 2)
# Constraints: weights sum to 1, all positive
constraints = [{"type": "eq", "fun": lambda w: np.sum(w) - 1}]
bounds = [
(0.01, None) for _ in range(n)
] # Minimum weight to avoid numerical issues
# Initial guess: inverse volatility weighting
vol = np.sqrt(np.diag(cov))
w0 = (1 / vol) / np.sum(1 / vol)
result = minimize(
objective, w0, method="SLSQP", constraints=constraints, bounds=bounds
)
return result.x
# Compute risk parity portfolio
w_rp = risk_parity_portfolio(true_cov)
rc_rp, rc_pct_rp = risk_contribution(w_rp, true_cov)Risk Parity Portfolio ============================================================ Portfolio volatility: 13.23% Asset Weight Vol Risk Contrib % of Total ------------------------------------------------------------ Asset A 27.00% 15.00% 0.0265 20.00% Asset B 18.43% 20.00% 0.0265 20.01% Asset C 15.33% 25.00% 0.0265 20.01% Asset D 22.48% 18.00% 0.0264 19.98% Asset E 16.75% 22.00% 0.0265 20.00% Total 100.00% - 0.1323 100.00%
Each asset now contributes approximately 20% of total portfolio risk, as intended. The risk parity weights are inversely related to asset volatility: low-volatility assets receive higher capital allocations, while high-volatility assets receive lower allocations. Asset A, with the lowest volatility at 15%, receives the highest weight, while Asset C, with the highest volatility at 25%, receives the lowest weight. This inverse relationship ensures that despite unequal capital allocations, each asset contributes equally to portfolio risk.
Risk Budgeting
Risk parity is a special case of a more general framework called risk budgeting, where we can specify arbitrary target risk contributions. Rather than requiring equal contributions from all assets, we might want specific allocations based on our views about asset classes or our risk tolerance. For example, we might want 50% of risk from equities and 50% from bonds, even if we hold only two equity assets and three bond assets. Or we might want to allocate more risk budget to assets we believe have higher Sharpe ratios.
# Custom risk budget: more risk from higher Sharpe assets
# Assume we believe Assets C and B have better risk-adjusted returns
custom_budget = np.array([0.15, 0.25, 0.25, 0.15, 0.20])
w_budget = risk_parity_portfolio(true_cov, risk_budget=custom_budget)
rc_budget, rc_pct_budget = risk_contribution(w_budget, true_cov)Risk Budgeting: Custom Risk Allocation ====================================================================== Asset Target Actual Weight ---------------------------------------------------------------------- Asset A 15.00% 14.95% 22.78% Asset B 25.00% 24.99% 22.54% Asset C 25.00% 25.02% 18.49% Asset D 15.00% 15.01% 19.04% Asset E 20.00% 20.03% 17.15%
The optimization successfully matches the target risk budget. Assets C and B, which we assigned higher risk budgets of 25%, receive larger risk allocations, while the capital weights adjust to account for both the target budget and the asset volatilities. Notice that even though Assets B and C have the same risk budget, their capital weights differ because they have different volatilities. The optimizer finds the unique set of weights that delivers the desired risk allocation.
Comparing Portfolio Approaches
Let us visualize how different portfolio construction methods allocate capital and risk, making the philosophical differences between approaches concrete and visible.
# Prepare data
methods = ["MVO", "Equal Weight", "Risk Parity"]
weights = [w_unconstrained, w_equal, w_rp]
# Risk contributions for each method
rc_mvo, rc_pct_mvo = risk_contribution(w_unconstrained, true_cov)
rc_eq, rc_pct_eq = risk_contribution(w_equal, true_cov)

The comparison highlights the structural differences between approaches. MVO chases returns by concentrating in Assets B and C, which have the highest expected returns, accepting that these assets will dominate portfolio risk. Equal weighting ignores both return forecasts and risk differences, treating all assets as interchangeable. Risk parity inversely weights by volatility to equalize risk contribution, focusing entirely on diversification without regard to expected returns. Each approach embodies different beliefs about what we can reliably estimate and what matters most for long-term performance.