# What is hierarchical risk parity (HRP)? Definition and example

Canonical URL: https://marketheist.io/portfolio/learn/hierarchical-risk-parity
By Jeffrey Lin · Published 2026-10-25 · Updated 2026-10-25 · Data through Sep 2026
Category: Construction

## Key takeaways

- Hierarchical risk parity weights a portfolio in three steps: cluster the holdings by correlation, reorder them so similar holdings are adjacent, then split the weight recursively between halves by inverse variance (uncertainty).
- HRP never inverts the covariance matrix, so it avoids the unstable, concentrated weights that minimum-variance optimisation can produce when holdings are highly correlated.
- The split happens at the midpoint of the ordered list, not at the branches of the tree, so a natural cluster can be cut in two; hierarchical equal risk contribution (HERC) splits at the real branches instead.
- HRP tends to give the most money to the calmest holdings and can concentrate heavily in a single low-volatility bond fund.
- MarketHeist's HRP uses correlation distance √(0.5(1 − ρ)), single linkage on that distance, and inverse-variance cluster variances, all on monthly returns.

## Definition

Hierarchical risk parity (HRP) is a portfolio weighting method that groups holdings into a tree by how closely their returns move together, orders them so similar holdings sit side by side, and then splits the money top-down between halves in inverse proportion to each half's variance (uncertainty). Introduced by Marcos López de Prado in 2016, it never inverts the covariance matrix, which makes it usable when holdings are highly correlated.

Also known as: HRP, hierarchical risk parity portfolio, López de Prado HRP, cluster-based risk parity.

## How it works

Classic portfolio optimisation inverts the covariance matrix. When holdings are highly correlated that inversion amplifies small estimation errors, and the weights swing to extremes. Hierarchical risk parity sidesteps the inversion by using the structure of the correlations instead.

Step one: tree clustering. Each pair of holdings gets a distance from its correlation, zero for a correlation of one and larger as the correlation falls. The two closest holdings join first, then the next closest clusters, until one tree remains. With single linkage, two clusters are as close as their most correlated pair.

Step two: quasi-diagonalization. Reading the leaves of the tree from left to right gives an order in which similar holdings sit next to each other. Reordering the covariance matrix this way pushes the large covariances toward the diagonal.

Step three: recursive bisection. Split the ordered list in half. Give each half a variance, measured as if its own holdings were weighted by inverse variance, and give the calmer half more weight in inverse proportion. Repeat inside each half until every holding has its weight.

Picture a company's budget passed down an org chart: the board splits it between two divisions by how risky each is, each division splits its share between two teams, and so on until every person has an amount. No one ever needs to see the whole company's numbers at once.

## Formula

**Correlation distance**

```
d_{i j} = \sqrt{\frac{1}{2} (1 - \rho_{i j})}
```

where:

- dᵢⱼ: distance between holdings i and j, from 0 (identical) to 1 (perfectly opposite)
- ρᵢⱼ: correlation of the monthly returns of holdings i and j

**Single linkage between clusters**

```
D (A,B) = \min_{a \in A, b \in B} d_{a b}
```

where:

- D(A, B): distance between clusters A and B; the pair of clusters with the smallest D merges next
- dₐᵦ: correlation distance between holding a in A and holding b in B

**Variance of a cluster (inverse-variance weights inside it)**

```
V (C) = \tilde{w}^T \Sigma_C \tilde{w}, \tilde{w}_i = \frac{1/\sigma_{i i}}{\sum_{j \in C}1/\sigma_{j j}}
```

where:

- C: a cluster: one half of the ordered list at some level of the bisection
- Σ_C: covariance matrix of the holdings in C
- w̃ᵢ: inverse-variance weight of holding i inside C
- σᵢᵢ: variance of holding i
- V(C): variance of cluster C at those weights

**The bisection split**

```
\alpha = 1 - \frac{V_L}{V_L + V_R}, w_i←\alpha w_i (i \in L), w_i←(1 - \alpha) w_i (i \in R)
```

where:

- L, R: left and right halves of the current list
- V_L, V_R: their cluster variances
- α: fraction of the current weight that goes to the left half
- wᵢ: weight of holding i, starting at 1 for every holding

The calmer half gets the larger share. Each holding's final weight is the product of the fractions it received at every split.

## Worked example

The five funds of the All Weather portfolio, VTI (US stocks), TLT (long Treasuries), IEF (intermediate Treasuries), GLD (gold) and DBC (commodities), from their monthly returns, Dec 2004 to Sep 2026.

Step one clusters the funds by correlation, and step two reads the tree's leaves into the order VTI, DBC, GLD, TLT, IEF, with funds that move together next to each other.

Step three splits that list in half again and again, giving each half weight in inverse proportion to its variance. The result puts 52.8% of the money in IEF, the calmest fund, 13.7% in VTI and 8.6% in DBC.

That concentration is HRP's known trade-off: IEF also carries 40.4% of the portfolio's risk, far more than any single fund's share under equal risk contribution (20.0%). In exchange, HRP's portfolio volatility was 6.5%, the lowest of the five weightings compared here, against 7.1% for equal risk contribution and 8.2% for equal weights.

Hierarchical equal risk contribution (HERC), which walks the actual branches of the tree and splits by cluster volatility rather than variance, spreads the money more evenly: its largest weight is 30.5%, against 52.8% for HRP.

On the co-movement groups count, HRP's weights hold 3.00 independent bets, against 3.79 for equal risk contribution and 3.92 for HERC.

Data through Sep 2026. Reproduce id: 8ee0adb30586beb9 (this guide, its lab setup and the data month).

## How MarketHeist computes it

- **Data**: Monthly total returns (dividends reinvested). Funds younger than the period shown are extended backward with older funds, spliced on returns, not prices.
- **Window**: The worked example and the lab use the common window of the holdings, Dec 2004 to Sep 2026 (262 months), ending at the data month of this page.
- **Inputs**: Population covariance (divides by N) and Pearson correlation of the funds' monthly returns over the full common window. The correlation drives the tree; the covariance drives the weights. (`hierarchicalRiskParity` in packages/portfolio/engine/hrp.ts)
- **Distance**: Correlation distance d = √(0.5(1 − ρ)), between 0 and 1. A tree height maps back to a correlation as ρ = 1 − 2d². (`correlationDistance` in packages/portfolio/engine/hrp.ts)
- **Linkage**: Single linkage: at each step the two clusters whose most correlated cross pair is highest merge, and the node's height is that pair's distance. MarketHeist clusters on d directly; the 2016 paper first builds a second distance matrix from the columns of d (a distance of distances) before linking. On an exact tie, the first pair the scan meets merges. (`linkageTree` in packages/portfolio/engine/hrp.ts)
- **Order**: The quasi-diagonal order is the tree's leaves read left to right (left subtree, then right subtree, recursively). (`leafOrder` in packages/portfolio/engine/hrp.ts)
- **Bisection**: Each list is split at its midpoint, with the smaller half on the left when the count is odd. A half's variance uses inverse-variance weights inside it; the left half gets 1 − V_L / (V_L + V_R) of the parent's weight. Splitting continues until every cluster is a single fund; the weights are then rescaled to sum to 1. A variance below 1e-18 is floored at 1e-18. (`recursiveBisection` in packages/portfolio/engine/hrp.ts)
- **HERC as implemented**: Same single-linkage tree, but the weight is passed down the actual branches from the root: at each node the left branch gets σ_R / (σ_L + σ_R), where σ is the square root of each branch's inverse-variance cluster variance, and the recursion runs down to single funds. It does not choose a number of clusters first or use other risk measures, both options in Raffinot's paper. (`hierarchicalEqualRiskContribution` in packages/portfolio/engine/hrp.ts)
- **Not used for the co-movement groups**: The Independent Bets groups are cut from a separate average-linkage tree; the single-linkage tree here is used only for HRP, HERC and the app's dendrogram. (`coMovementTree` in packages/portfolio/engine/overlap.ts)
- **Engine functions**: `inverseVolWeights` (packages/portfolio/engine/risk.ts), `equalRiskContributionWeights` (packages/portfolio/engine/risk.ts), `hierarchicalRiskParity` (packages/portfolio/engine/hrp.ts), `hierarchicalEqualRiskContribution` (packages/portfolio/engine/hrp.ts), `weightingStats` (packages/portfolio/engine/risk.ts), `effectiveBets` (packages/portfolio/engine/overlap.ts)

## Hierarchical risk parity (HRP) compared with its neighbours

Hierarchical risk parity compared with other risk-based weightings

| Method | Uses correlations | Inverts the covariance matrix | Follows the tree | Typical result |
| --- | --- | --- | --- | --- |
| Equal weight | No | No | No | Volatile holdings dominate the risk |
| Inverse volatility | No | No | No | Tilts toward calm holdings |
| Equal risk contribution (ERC) | Yes, every pair | No, solved iteratively | No | Equal risk per holding |
| Hierarchical risk parity (HRP) | Through the tree and within each half | No | For the order only; splits at list midpoints | Can concentrate in the calmest holding |
| Hierarchical equal risk contribution (HERC) | Through the tree | No | Yes, splits at the real branches | Spreads weight more evenly across clusters |
| Minimum variance | Yes | Yes | No | Sensitive to estimation error; often concentrated |

## Limitations

- Splitting at list midpoints ignores where the tree actually branches. A tight cluster can be cut in two, and a lone fund can be paired with a cluster it has little to do with. HERC was proposed to fix this.
- Because each split favours the calmer side, HRP can put a large share of the money, and of the risk, into one low-volatility fund.
- Single linkage chains: a fund joins a cluster through its single most correlated member, so loosely related funds can end up in the same branch.
- The tree is discrete. A small change in correlations can reorder the leaves and move the weights noticeably, so the method is stable against matrix inversion problems but not against every change in the data.
- The weights here come from the whole window. Holding them from the start of a backtest would use information from later years. HRP also ignores expected returns entirely.

## Frequently asked questions

**How is hierarchical risk parity different from risk parity?**

Equal risk contribution, the usual risk parity, makes every holding carry the same share of risk using the full covariance matrix. HRP uses a correlation tree and splits weight between halves of an ordered list, so holdings in a crowded cluster share their branch's weight instead of each getting a full share.

**Why does it matter that HRP does not invert the covariance matrix?**

Inverting a covariance matrix of highly correlated assets magnifies estimation errors, which makes minimum-variance and mean-variance weights unstable. HRP only ever divides by individual and cluster variances, which are well behaved.

**What is quasi-diagonalization?**

Reordering the holdings so that ones in the same branch of the tree sit next to each other. The covariance matrix in that order has its large values near the diagonal, which is what lets the bisection step treat neighbouring holdings as a group.

**What is HERC?**

Hierarchical equal risk contribution, proposed by Thomas Raffinot in 2018. It uses the same kind of tree but passes weight down the real branches instead of list midpoints, and splits by risk at each branch, which usually spreads the money more evenly than HRP.

**Does HRP perform better than other weightings?**

López de Prado's 2016 simulations found lower out-of-sample variance than minimum-variance weights. Later studies on real data report mixed results that depend on the assets and the period. The worked example on this page compares weights and risk shares, not future performance.

## References

1. López de Prado, M. (2016) Building Diversified Portfolios that Outperform Out of Sample <https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2708678>. Journal of Portfolio Management 42(4). The original HRP algorithm.
2. Raffinot, T. (2018) The Hierarchical Equal Risk Contribution Portfolio <https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3237540>. HERC.
3. Raffinot, T. (2017) Hierarchical Clustering-Based Asset Allocation. Journal of Portfolio Management 44(2).
4. López de Prado, M. (2018) Advances in Financial Machine Learning. Wiley. Chapter 16 covers HRP.

## Try it

App: https://marketheist.io/portfolio/p/all-weather

MCP prompt (MarketHeist MCP server, https://marketheist.io/mcp):

```
Using MarketHeist, show the correlation clustering order and the risk share of each holding for VTI, TLT, IEF, GLD and DBC at equal weights, and the equal-risk weights
```

Historical simulation, not advice.
