When Risk-Parity Portfolios Can Have Negative Weights
Summary
The document explains that negative weights in risk-parity portfolios depend on the construction method and its constraints. An inverse-volatility allocation is positive by design, and many full optimization implementations impose nonnegative weights. Without that restriction, however, an optimizer can produce negative holdings while equalizing asset risk contributions.
A covariance-matrix example demonstrates a package result with positive weights under its default settings and a negative weight when the lower bound is relaxed. The example also shows that strongly dependent assets can make risk-contribution calculations sensitive to inputs and optimization convergence: increasing the iteration limit changes the reported contributions. Thus negative weights are possible, but the result depends on the objective, constraints, covariance estimates, and numerical behavior; the example is not a guarantee about every implementation or dataset.
Key ideas
- Inverse-volatility weights are positive by construction.
- Full risk-parity optimizations may impose nonnegative weights, but negative weights can occur when they do not.
- The cited package example permits a negative holding when its lower weight bound is relaxed.
- Strong asset dependencies can make risk-contribution estimates sensitive to small input changes.
- Optimization settings and covariance estimates affect the resulting weights and contributions.
Tags
Full text
# When optimizing a portfolio for risk parity, can any portfolio weights turn negative?
# When optimizing a portfolio for risk parity, can any portfolio weights turn negative?
As the title reads, when performing risk parity optimization (equal risk contribution amongst all assets to the portfolio volatility), is it possible for weights to turn negative?
I understand that in the regular portfolio optimization, it is necessary to set a short sales restriction, if not it is possible to have negative weights in the mean-variance optimization or the "burst" of weights.
However, I saw that in packages of R such as "riskParityPortfolio" there isn't a selection for short sale restrictions. Does that mean that the risk parity optimization inherently does not result in negative weights?
## Answer by Enrico Schumann (score 4, accepted)
https://quant.stackexchange.com/a/78913
Many risk-parity implementations simply use the inverse-vol rule (i.e. weights are proportional to 1 over vol), and then all weights are (strictly) positive by construction.
A number of implementations that do the full optimization indeed set non-negativity as an explicit constraint. But in general and without such constraints, negative weights may occur when you equalize risk-contributions (though negative weights may be unlikely).
An example in R for a 4-by-4 covariance matrix, which is of rank 4 and positive definite:
```
S <- structure(c(0.000366309632978563, -0.000105943107569848,
-0.000119667135542588, 0.000169622848883779,
-0.000105943107569848, 0.000187730511335559,
-6.49497066288097e-05, -0.000167162505503921,
-0.000119667135542588, -6.49497066288097e-05,
0.000102201079006482, 1.88829418811814e-05,
0.000169622848883779, -0.000167162505503921,
1.88829418811814e-05, 0.000208993337170307),
dim = c(4L, 4L))
```
The implied correlation matrix:
```
cov2cor(S)
## [,1] [,2] [,3] [,4]
## [1,] 1.000 -0.404 -0.618 0.613
## [2,] -0.404 1.000 -0.469 -0.844
## [3,] -0.618 -0.469 1.000 0.129
## [4,] 0.613 -0.844 0.129 1.000
```
I do not use the `riskParityPortfolio` package, but it seems to support negative weights, though the default is to not allow them:
```
library("riskParityPortfolio")
riskParityPortfolio(S)
## $w
## [1] 0.2313 0.2990 0.4588 0.0109
##
## $relative_risk_contribution
## [1] -1.9471 -0.0858 1.5197 1.5132
## ....
riskParityPortfolio(S, w_lb = -1)
## $risk_concentration
## [1] 1.93e-14
##
## $w
## [1] -0.0829 0.4391 0.2167 0.4271
##
## $relative_risk_contribution
## [1] 0.25 0.25 0.25 0.25
## ....
```
Additional note: The example covariance-matrix hides some fairly-strong dependencies between the asset returns, which may not be obvious from looking at the data:
```
library("NMOF")
R <- randomReturns(na = 4, ns = 100,
sd = sqrt(diag(S)),
rho = cov2cor(S), exact = TRUE)
pairs(R)
```
Computations based on such a matrix (such as a marginal-risk calculation) will typically be sensitive and react strongly to small changes ("perturbations") of inputs. In the example, you can get around this by increasing the iterations:
```
w <- riskParityPortfolio(S)$w
FRAPO::mrc(w, S)
## [1] -194.71 -8.58 151.97 151.32
w <- riskParityPortfolio(S, maxiter = 1e4)$w
FRAPO::mrc(w, S)
## [1] -67.3 11.2 78.2 77.9
w <- riskParityPortfolio(S, maxiter = 1e5)$w
FRAPO::mrc(w, S)
## [1] 23.1 24.7 26.1 26.1
w <- riskParityPortfolio(S, maxiter = 1e6)$w
FRAPO::mrc(w, S)
## [1] 25 25 25 25
```
(I use the marginal-risk function `mrc` from Bernhard Pfaff's `FRAPO` package.) But of course, this is all the result of an empirical problem (not a computational one): the assets are highly-correlated, and so an algorithm will always have trouble differentiating between linear combinations of those assets.Shown 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.