Applying Box Constraints to Hierarchical Risk Parity Weights
Summary
The question asks how to keep hierarchical risk parity allocations within per-asset bounds while preserving the method’s recursive allocation across correlation clusters. One proposed approach examines each pair of branches at every split. It calculates each branch’s current total weight and number of constituent assets, then derives a feasible interval for the branch scaling factor so that every leaf can still satisfy the specified minimum and maximum weight.
The scaling factor is clipped to that interval as the recursion proceeds. If the interval is infeasible, the answer recommends terminating, though it does not prove that infeasibility only arises when the overall constraints conflict. The method is aimed at individual asset box constraints; the author warns that constraints on aggregate groups such as sectors may not fit the clustering structure. A second answer proposes rescaling branch allocations, but gives little justification. No implementation results or formal validation are reported.
Key ideas
- At each cluster split, branch weights can be bounded using the number of assets and their current aggregate weight.
- A feasible interval for the branch scaling factor helps preserve minimum and maximum leaf weights.
- The proposed procedure clips the original allocation factor to that interval during recursion.
- Aggregate constraints such as sector limits may be difficult to impose within the hierarchical structure.
- The feasibility argument and practical performance are not demonstrated.
Tags
Full text
# Hierarchical Risk Parity with allocation constraints?
# Hierarchical Risk Parity with allocation constraints?
In the really interesting paper by Marcos Lopez de Prado a variation of risk parity is applied whereby the underlying assets of the portfolio are first split in 'correlation clusters' and the allocation percentages are distributed based on that.
More specifically, the allocation algorithm is initially splitting the assets in two groups and assigning a variance-based allocation in these, while proceeding with a tree-like recursive procedure for the members of the two initial groups.
This results in the weights being in [0,1], however, as mentioned a couple of times in the paper, this can be easily modified so as to accommodate different constraints. Any idea on how this would be possible? For example, how can I get the weights to be in the range [0.01 0.1]?
## Answer by vanguard2k (score 4)
https://quant.stackexchange.com/a/37114
EDITED
You are right. We have to look town to the "leaves" in each iteration. I would do it the following way:
If $L_i^{(j)}$ is the set of indices in the $j$ branch ($j \in \{1,2\}$), then we define $s_i^{(j)}=\sum_{n \in L_i^{(j)}w_n}$, the weight of the branch before scaling and $n_i^{(j)}=\left|L_i^{(j)}\right|$ the number of leaves in the branch.
The box constraints for the weights we call $w_\text{min}$ and $w_\text{max}$.
Let $\alpha_i$ be the scaling factor for $L_i^{(1)}$ and $1-\alpha_i$ the scaling factor for $L_i^{(2)}$.
To fulfill the constraints, we need to check the resulting weights.
If we scale the weights of $L_i^{(j)}$ by $\alpha_i$, we must have enough room to maneuver so that the minimum weight constraint can still fit into the branch weight and we must have a limited weight in order to be able to fulfil the upper bounds:
$$ \alpha_i s_i^{(1)} \geq n_i^{(1)} w_\text{min}$$ $$ \alpha_i s_i^{(1)} \leq n_i^{(1)} w_\text{max}$$
For the other side of the branch, we need to check, the analogue thing:
$$ (1-\alpha_i) s_i^{(2)} \geq n_i^{(2)} w_\text{min}$$ $$ (1-\alpha_i) s_i^{(2)} \leq n_i^{(2)} w_\text{max}$$
If we put all four of them together, we get the following inequalities for $\alpha_i$:
$$ \text{max}\left(1-\frac{n_i^{(2)}w_\text{max}}{s_i^{(2)}},\frac{n_i^{(1)}w_\text{max}}{s_i^{(1)}}\right) \leq \alpha_i \leq \text{min}\left(1-\frac{n_i^{(2)}w_\text{min}}{s_i^{(2)}},\frac{n_i^{(1)}w_\text{max}}{s_i^{(1)}}\right)$$
So if we define the lower bound as $\text{LB}_i$ and the upper bound as $\text{UB}_i$, we adjust the scaling factor as follows:
$$ \hat{\alpha}_i = \text{max}(\text{LB}_i,\text{min}(\alpha_i,\text{UB}_i))$$
If $\text{UB}_i \leq \text{LB}_i$, then terminate the function. I hope this only happens if the constraints are incompatible but I didnt attempt a proof.
This way, you can proceed with the algorithm while fulfilling the constraints.
Linear constraints on sigle assets are probably the only useful type of constraints you can impose. Constraints on sector weights for example will be impossible here due to the clustering structure. In practice, I can see this being a big drawback.
Compared to the classical inverse volatility Risk Budgeting, this approach is really elegant, since it only ignores the part of the variance covariance matrix that is of little importance if you will.
## Answer by pyCthon (score -1)
https://quant.stackexchange.com/a/37109
On formula 3.c on page 8 in his paper.
We have:
$\alpha = 1 - v_1/(v_1 + v_2$)
Where a ~ (0,1), therefore $v_1$ and $v_2$ are both between (0,1) and sum to 1 as well. So we can scale both $v_1$ and $v_2$ appropriately ex:
$v^{new}_1 = (1-0.01) * v_1 + 0.01$
This would give us the desired weight rangeShown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.