Search code examples
pythonequationportfoliononlinear-functions

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?


Solution

  • 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)