RBP

Defined in fynance.portfolio.allocation

RBP(X, budgets=None, w0=None, up_bound=1., low_bound=0., cov=None)[source]

Get weights of a Risk Budgeting Portfolio allocation.

Generalizes ERC to arbitrary per-asset risk budgets: instead of equalizing risk contributions, each asset i is allocated a target share b_i of total portfolio variance, with \(\sum_i b_i = 1\). Passing budgets=None falls back to the equal-budget case \(b_i = 1/N \, \forall i\), which reproduces ERC.

The optimizer (SLSQP) minimizes a smooth least-squares surrogate of the gap between each asset’s risk contribution and its target budget, under sum-to-one and box constraints.

Parameters:
Xarray_like

Each column is a series of price or return’s asset.

budgetsarray_like, optional

Target risk budget per asset, length N, strictly positive entries summing to 1 (within 1e-8, silently renormalized inside that tolerance). Default None spreads the budget equally (\(b_i = 1/N\)), reproducing ERC.

w0array_like, optional

Initial weights for the optimizer.

up_bound, low_boundfloat, optional

Respectively maximum and minimum values of weights, such that low_bound \(\leq w_i \leq\) up_bound \(\forall i\). Default is 0 and 1.

covcallable, optional

Callable mapping the (T, N) training array to an (N, N) covariance matrix, e.g. fynance.portfolio.covariance.ledoit_wolf; default None keeps the sample covariance.

Returns:
array_like

Weights whose risk contributions match budgets.

Raises:
ValueError

If budgets does not have length N, contains a non-positive entry, or its sum deviates from 1 by more than 1e-8.

See also

ERC
fynance.portfolio.attribution.risk_contribution

Notes

Weights of the Risk Budgeting Portfolio, as described by T. Roncalli [6], verify the following problem:

\[\begin{split}w = \text{arg min } f(w) \\ u.c. \begin{cases}w'e = 1 \\ 0 \leq w_i \leq 1 \\ \end{cases}\end{split}\]

With:

\[f(w) = \sum_{i=1}^{N} \left( w_i (\Omega w)_i - b_i \, w' \Omega w \right)^2\]

Where \(\Omega\) is the variance-covariance matrix of X, \(N\) the number of assets and \(b\) the target risk-budget vector (with \(\sum_{i=1}^{N} b_i = 1\)). With \(b_i = 1/N \, \forall i\) this objective shares the same minimizers as ERC’s (both vanish exactly when every asset’s risk contribution matches its budget).

References

[6]

T. Roncalli, “Introduction to Risk Parity and Budgeting”, 2013, https://arxiv.org/abs/1403.1889

Examples

Two independent assets with volatilities sigma_1=0.01 and sigma_2=0.03: for a diagonal covariance the risk-budgeting first-order condition reduces to \(w_i \sigma_i \propto \sqrt{b_i}\), i.e. \(w_i \propto \sqrt{b_i} / \sigma_i\).

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> sigma1, sigma2 = 0.01, 0.03
>>> X = np.column_stack([
...     rng.normal(0.0, sigma1, 2000),
...     rng.normal(0.0, sigma2, 2000),
... ])
>>> b = np.array([0.8, 0.2])
>>> w = RBP(X, budgets=b)
>>> w.shape
(2, 1)
>>> bool(np.isclose(w.sum(), 1.0))
True
>>> expected = np.sqrt(b) / np.array([sigma1, sigma2])
>>> expected = expected / expected.sum()
>>> bool(np.allclose(w.flatten(), expected, atol=1e-2))
True