Как решить распределение паритета риска с помощью Python

Я хотел бы решить проблему паритета рисков с помощью python.

Паритет риска — классический подход к построению портфеля в финансах. Основная идея состоит в том, чтобы убедиться, что вклад риска для каждого актива одинаков.

Например, предположим, что имеется 3 актива и известна ковариационная матрица доходности активов:

(var_11,var_12,var_13

var_12,var_22,var_23

var_13,var_23,var_33) 

Я хотел бы придумать вес портфеля для этих активов (w1,w2,w3), чтобы:

w1+w2+w3=1

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

а вклад риска для каждого актива равен:

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

Я не уверен, как решить эти уравнения с помощью python, кто-нибудь может пролить свет на это?


person cone001    schedule 06.07.2016    source источник
comment
Это не похоже на вопрос программирования как таковой и, следовательно, не по теме. Возможно, лучше подходит для других сайтов StackExchange, которые больше ориентированы на математику?   -  person EdChum    schedule 06.07.2016


Ответы (3)


Опоздал на это более чем на год, но используйте numpy и scipy Solver. Этот парень хорошо объясняет и делает это на питоне.

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

Вся заслуга принадлежит парню, который написал сообщение в блоге. Это код в блоге...

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)
person WhitneyChia    schedule 18.12.2017

Я только что выпустил пакет Python для решения классической проблемы паритета рисков.

В основном ваша проблема может быть решена в одной строке:

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

Где cov — ковариационная матрица активов, а b — желаемый вектор бюджета. Кроме того, пакет допускает произвольные линейные ограничения равенства и неравенства, а также добавление объективных терминов, таких как средняя доходность и волатильность. Проверьте это: https://mirca.github.io/riskparity.py и https://github.com/mirca/riskparity.py

person Zé Vinícius    schedule 25.07.2019

Вот решение Python, основанное на странице Википедии о паритете рисков. Фрейм данных returns содержит десятичные ежедневные доходы от Yahoo Finance.

R = 252*returns.mean().to_numpy()
V = 252*returns.cov().to_numpy()

def port_ret(w, R):
    return np.dot(w.T, R)

def port_sd(w, V):
    return np.sqrt(np.dot(w.T, np.dot(V, w)))

def contrib_sd(w, V):
    return w * np.dot(V, w) / port_sd(w, V)

def f(w, V):
    ratio = port_sd(w, V)**2 / (np.dot(V, w) * len(w))
    return ((w - ratio)**2).sum()

result = sco.minimize(
    fun=f,
    x0=np.ones_like(R) / len(R),
    args=(V,),
    bounds=tuple((0,1) for i in range(returns.shape[1])),
    constraints=({'type': 'eq', 'fun': lambda x: x.sum() - 1})
)

Вот код, который объединяет данные Yahoo Finance. Вам нужно будет изменить пути к файлам.

# reads and combines .csv files into one data frame of returns
# VTI - market-cap weighted ETF of all U.S. stocks
# IEI - ETF of 3-7 year maturity Treasuries
# TLT - ETF of 20+ year maturity Treasuries
# GLD - Gold ETF
tickers = ['VTI', 'IEI', 'TLT', 'GLD']
temp = []
for t in tickers:
    temp.append(
        pd.read_csv(
            '../data/' + t + '-2021-04-04.csv', 
            index_col='Date', 
            parse_dates=True, 
            usecols=['Date', 'Adj Close'])
    )

# in pd.concat()
# axis=1 joins the data frames side-by-side
# join='inner' finds the common set of dates
adj_closes = pd.concat(temp, axis=1, join='inner')
adj_closes.columns = tickers
returns = adj_closes.pct_change().dropna()
del temp
person Richard Herron    schedule 10.04.2021