PyPortfolioOpt icon indicating copy to clipboard operation
PyPortfolioOpt copied to clipboard

How to add Risk Contribution/Risk Parity Constraint?

Open x829901 opened this issue 3 years ago • 2 comments

In the following code, I have two questions.

  1. How do I add a risk parity constraint where each holding contributes an equal amount of risk?
  2. How do I add a risk contribution constraint to, for example, constrain portfolio to no more than 50% of the portfolio's risk can be allocated to growth stocks?
ef = efficient_frontier.EfficientFrontier(mu, S)
ef.add_constraint(lambda w: w @ growth == w @ value)
ef.add_constraint(lambda w: w @ largecap >= w @ midcap)
ef.add_constraint(lambda w: w @ midcap >= w @ smallcap)
ef.add_sector_constraints(region_mapper, region_lower, region_upper)
ef.add_sector_constraints(size_mapper, size_lower, size_upper)
ef.add_sector_constraints(style_mapper, style_lower, style_upper)
ef.add_sector_constraints(type_mapper, type_lower, type_upper)
ef.add_sector_constraints(asset_mapper, asset_lower, asset_upper)
ef.add_sector_constraints(sector_mapper, sector_lower, sector_upper)
ef.min_volatility()
weights = ef.clean_weights(0.005)

For reference, here is how I am calculating risk contribution from each asset in a portfolio.

p = prices
S = risk_models.risk_matrix(p, 'sample_cov')
pvar = np.dot(w.T, np.dot(S, w))
pvol = np.sqrt(np.dot(w.T, np.dot(S, w)))
pvolw = ((np.dot(w, S)) / pvar) * w

w is the portfolio's % weighting for each ticker as a pandas Series, (screenshot below).

image

pvolw is the pandas Series of each holding's risk contribution as a percentage of total portfolio risk (screenshot below). For example, you'll see that stock ticker AB US Equity is contributing 1.6546% to the portfolio risk volatility.

image

x829901 avatar Feb 26 '21 03:02 x829901

Hi @x829901,

Unfortunately that isn't currently possible. Risk contribution / risk parity is not a convex problem in general, though for simple constraints there is an equivalent convex problem (see page 46 here).

There is a python library called riskparity.py that can solve these problems, and I recently got permission from the authors to build it into PyPortfolioOpt, but that won't happen for several months.

Best, Robert

robertmartin8 avatar Feb 26 '21 03:02 robertmartin8

Ok thanks. Yes, it would very useful to constrain risk weightings. Cash weightings can be deceptive in terms of how much risk exposure there actually within the portfolio.

x829901 avatar Feb 26 '21 21:02 x829901