Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to solve risk parity allocation using Python

I would like to solve risk parity problem using python.

Risk parity is a classic approach for portfolio construction in finance. The basic idea is to make sure the risk contribution for each asset is equal.

For example, suppose there're 3 assets, and the co-variance matrix for the asset returns is known:

(var_11,var_12,var_13

var_12,var_22,var_23

var_13,var_23,var_33) 

I'd like to come up with a portfolio weight for these assets (w1,w2,w3) so that:

w1+w2+w3=1

w1>=0
w2>=0
w3>=0

and the risk contribution for each asset equals:

w1^2*var_11+w1*w2*var_12+w1*w3*var_13

=w2^2*var_22+w1*w2*var_12+w2*w3*var_23

=w3^2*var_33+w1*w3*var_13+w2*w3*var_23

I am not sure how to solve these equations using python, anyone could shed some light on this?

like image 632
cone001 Avatar asked Oct 19 '25 12:10

cone001


2 Answers

Over a year late to this, but use numpy and a scipy solver. This guy explains it well and does it in python.

https://thequantmba.wordpress.com/2016/12/14/risk-parityrisk-budgeting-portfolio-in-python/

All credit goes to the guy who wrote the blog post. This is the code in the blog...

from __future__ import division
import numpy as np
from matplotlib import pyplot as plt
from numpy.linalg import inv,pinv
from scipy.optimize import minimize

 # risk budgeting optimization
def calculate_portfolio_var(w,V):
    # function that calculates portfolio risk
    w = np.matrix(w)
    return (w*V*w.T)[0,0]

def calculate_risk_contribution(w,V):
    # function that calculates asset contribution to total risk
    w = np.matrix(w)
    sigma = np.sqrt(calculate_portfolio_var(w,V))
    # Marginal Risk Contribution
    MRC = V*w.T
    # Risk Contribution
    RC = np.multiply(MRC,w.T)/sigma
    return RC

def risk_budget_objective(x,pars):
    # calculate portfolio risk
    V = pars[0]# covariance table
    x_t = pars[1] # risk target in percent of portfolio risk
    sig_p =  np.sqrt(calculate_portfolio_var(x,V)) # portfolio sigma
    risk_target = np.asmatrix(np.multiply(sig_p,x_t))
    asset_RC = calculate_risk_contribution(x,V)
    J = sum(np.square(asset_RC-risk_target.T))[0,0] # sum of squared error
    return J

def total_weight_constraint(x):
    return np.sum(x)-1.0

def long_only_constraint(x):
    return x

x_t = [0.25, 0.25, 0.25, 0.25] # your risk budget percent of total portfolio risk (equal risk)
cons = ({'type': 'eq', 'fun': total_weight_constraint},
{'type': 'ineq', 'fun': long_only_constraint})
res= minimize(risk_budget_objective, w0, args=[V,x_t], method='SLSQP',constraints=cons, options={'disp': True})
w_rb = np.asmatrix(res.x)
like image 109
WhitneyChia Avatar answered Oct 21 '25 00:10

WhitneyChia


I've just released a python package to solve the classical risk parity problem.

Basically your problem can be solved in one line:

import riskparityportfolio as rp
optimum_weights = rp.vanilla.design(cov, b)

Where cov is the covariance matrix of the assets and b is the desired budget vector. Additionally, the package allows for arbitrary linear equality and inequality constraints as well as the addition of objective terms like the mean return and the volatility. Check it out: https://mirca.github.io/riskparity.py and https://github.com/mirca/riskparity.py

like image 24
Zé Vinícius Avatar answered Oct 21 '25 01:10

Zé Vinícius