ERC

Defined in fynance.portfolio.allocation

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

Get weights of Equal Risk Contribution portfolio allocation.

Risk-parity allocation: each asset contributes the same amount of total portfolio variance. ERC sits between the naive 1/N and the minimum-variance portfolio — it requires only the covariance matrix and is robust to noisy expected returns, which makes it a common choice when return forecasts are unreliable.

The optimizer (SLSQP) minimizes a smooth surrogate of the risk-contribution dispersion under sum-to-one and box constraints.

Parameters:
Xarray_like

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

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 that minimize the Equal Risk Contribution portfolio.

Notes

Weights of Equal Risk Contribution, as described by S. Maillard, T. Roncalli and J. Teiletche [1], 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) = N \sum_{i=1}^{N}w_i^2 (\Omega w)_i^2 - \sum_{i,j=1}^{N} w_i w_j (\Omega w)_i (\Omega w)_j\]

Where \(\Omega\) is the variance-covariance matrix of X and \(N\) the number of assets.

References

Examples

>>> import numpy as np
>>> from fynance.portfolio.covariance import ledoit_wolf
>>> rng = np.random.default_rng(0)
>>> X = rng.normal(0.0, 0.01, size=(200, 4))
>>> w = ERC(X, cov=ledoit_wolf)
>>> w.shape
(4, 1)
>>> bool(np.isclose(w.sum(), 1.0))
True