2/4/22, 2:54 PM Vanilla Risk Parity | Python | Riskfolio-Lib | Medium
Vanilla Risk Parity with Python and Riskfolio-
Lib
What is Vanilla Risk Parity?
Vanilla Risk Parity is a portfolio optimization technique that was developed to overcome
the drawbacks of traditional mean variance model. The main idea of this model is to put
constraints on the risk that each asset contribute to the total risk of the portfolio, this
approach is known as risk budgeting. To do this is necessary that the risk measure satisfy
the Euler decomposition. Roncalli (2012) proposes the general portfolio optimization
problem for vanilla risk parity:
Vanilla Risk Parity Problem (Roncalli (2012))
How to use Vanilla Risk Parity with Riskfolio-Lib?
First, you need to install Riskfolio-Lib. You must run the following code:
[Link] 1/7
2/4/22, 2:54 PM Vanilla Risk Parity | Python | Riskfolio-Lib | Medium
pip install Riskfolio-Lib
After install it, you need to download some asset prices, for example using yfinace we can
download some data:
import numpy as np
import pandas as pd
import yfinance as
yf
yf.pdr_override()
[Link].float_format = '{:.4%}'.format
# Date range
start = '2016-01-01'
end = '2019-12-30'
# Tickers of assets
assets = ['JCI', 'TGT', 'CMCSA', 'CPB', 'MO', 'APA', 'MMC', 'JPM',
'ZION', 'PSA', 'BAX', 'BMY', 'LUV', 'PCAR', 'TXT', 'TMO',
'DE', 'MSFT', 'HPQ', 'SEE', 'VZ', 'CNP', 'NI', 'T', 'BA']
[Link]()
# Downloading data
data = [Link](assets, start = start, end = end)
data = [Link][:,('Adj Close', slice(None))]
[Link] = assets
# Calculating returns
Y = data[assets].pct_change().dropna()
display([Link]())
Then we need to build the portfolio object, this object contains all portfolio models based
on convex programming. In this case, we are going to calculate the equal risk
[Link] 2/7
2/4/22, 2:54 PM Vanilla Risk Parity | Python | Riskfolio-Lib | Medium
contribution portfolio, that is the portfolio that equally distribute the risk among all
assets:
import riskfolio as rp
# Building the portfolio object
port = [Link](returns=Y)
# Calculating optimal portfolio
# Select method and estimate input parameters:
method_mu='hist' # Method to estimate expected returns based on
historical data.
# Method to estimate covariance matrix based on
method_cov='hist'
historical data.
port.assets_stats(method_mu=method_mu, method_cov=method_cov, d=0.94)
# Estimate optimal portfolio:
model='Classic' # Could be Classic (historical) or FM (Factor Model)
rm = 'MV' # Risk measure used, this time will be variance
hist = True # Use historical scenarios for risk measures that depend on
scenarios
rf = 0 # Risk free rate
b = None # Risk contribution constraints vector
w_rp = port.rp_optimization(model=model, rm=rm, rf=rf, b=b, hist=hist)
display(w_rp.T)
As you can see, we get an optimal portfolio. This portfolio is the equal risk contribution
portfolio. If we want to distribute the risk in another way, we can change the input
parameter b (use a custom array) that represent the constraint on risk contribution of
each asset. If we want to see the structure of the portfolio, we can plot a pie chart:
# Plotting the composition of the portfolio
ax = rp.plot_pie(w=w_rp,
title='Risk Parity Variance',
[Link] 3/7
2/4/22, 2:54 PM Vanilla Risk Parity | Python | Riskfolio-Lib | Medium
others=0.05,
nrow=25,
cmap = "tab20",
height=6,
width=10,
ax=None)
Compared to classical mean risk portfolio optimization models, this technique produces
most diversified portfolios.
On the other hand, the objective of this technique is to distribute risk among all assets.
To see this property, we can plot the risk contribution per asset using the following code:
# Plotting the risk contribution per asset
mu = [Link]()
cov = [Link]()
# Covariance matrix
returns = Y # Returns of the assets
ax = rp.plot_risk_con(w=w_rp,
cov=cov,
returns=returns,
rm=rm,
rf=0,
alpha=0.05,
color="tab:blue",
height=6,
[Link] 4/7
2/4/22, 2:54 PM Vanilla Risk Parity | Python | Riskfolio-Lib | Medium
width=10,
t_factor=252,
ax=None)
We notice when we see the plot above, it is that the vanilla risk parity model can make
that the risk contribution of each asset be equal.
Until now, we have working using variance as risk measure, however Riskfolio-Lib has
10 risk measures available for vanilla risk parity portfolios, to compare asset allocation
based on the 10 risk measures using vanilla risk parity, we must run the following code:
# Risk Measures available:
#
#
'MV': Standard Deviation.
# 'MAD': Mean Absolute Deviation.
# 'MSV': Semi Standard Deviation.
# 'FLPM': First Lower Partial Moment (Omega Ratio).
# 'SLPM': Second Lower Partial Moment (Sortino Ratio).
# 'CVaR': Conditional Value at Risk.
# 'EVaR': Entropic Value at Risk.
# 'CDaR': Conditional Drawdown at
Risk of uncompounded cumulative
returns.
Entropic Drawdown at Risk of uncompounded cumulative returns.
# 'EDaR':
# 'UCI': Ulcer Index of uncompounded cumulative returns.
rms = ['MV', 'MAD', 'MSV', 'FLPM', 'SLPM', 'CVaR',
[Link] 5/7
2/4/22, 2:54 PM Vanilla Risk Parity | Python | Riskfolio-Lib | Medium
'EVaR', 'CDaR', 'UCI', 'EDaR']
w_s = [Link]([])
for i in rms:
w = port.rp_optimization(model=model, rm=i, rf=rf, b=b, hist=hist)
w_s = [Link]([w_s, w], axis=1)
w_s.columns = rms
w_s.[Link]("{:.2%}").background_gradient(cmap='YlGn')
[Link] 6/7
2/4/22, 2:54 PM Vanilla Risk Parity | Python | Riskfolio-Lib | Medium
We can made a bar plot comparing asset allocation of each risk measure:
import [Link] as plt
# Plotting a comparison of assets weights for each portfolio
fig = [Link]()
fig.set_figwidth(16)
fig.set_figheight(6)
ax = [Link](nrows=1, ncols=1)
w_s.[Link](ax=ax)
Thanks for reading, here are some links related to the project:
GitHub: [Link]
Documentation: [Link]
Pypi: [Link]
Contact
You can contact us by email [Link]@[Link] or
Linkedin [Link]
[Link] 7/7