Я создаю паритетный портфель риска, в котором вклад риска («RC») каждого актива в риск портфеля должен быть одинаковым. Учитывая приведенный ниже пример с тремя активами, ограничение должно быть примерно таким:
def constraint2(x):
return RC[0] = RC[1] = RC[2]
Вклад каждого актива в риск портфеля должен быть одинаковым для каждого элемента вектора RC. Как я могу реализовать подобные ограничения, используя scipy.optimize?
Используя Excel, я получил следующие веса Портфеля: A = 15%, B = 73%, C = 12%.
Любая помощь высоко ценится! :)
Пожалуйста, найдите мой образец кода ниже.
def risk_contribution(w):
pf_var = np.matrix(w) * np.matrix(cova) * np.transpose(np.matrix(w)) #calculate Portfolio variance
MRC = np.matrix(cova) * np.transpose(np.matrix(w)) #Marginal risk contribution
RC = np.multiply(np.transpose(np.matrix(w)),np.matrix(MRC)) #Risk contribution
sum_RC = np.sum(np.matrix(RC))
return sum_RC
RW = np.divide(np.matrix(RC),np.matrix(pf_var))
def constraint1(w):
return np.sum(w) - 1
w0 = np.matrix([0.333, 0.333, 0.333])
cova = [0.04,0.002,0.03],[0.002,0.003,0.001],[0.03,0.001,0.063]
con1 = {"type": "eq", "fun": constraint1}
cons = [con1]
b = (0,None)
bnds = (b,b,b)
print(minimize(risk_contribution, w0, method="SLSQP", bounds=bnds, constraints=cons))
EDIT:
Таким образом, я придумал следующий Кодекс, который немного отличается от предыдущего Кодекса, поскольку он сводит к минимуму возведенную в квадрат разницу между каждым вкладом риска в актив и целью риска. Я получаю тот же результат для цели J, что и в Excel, но при выполнении оптимизации оптимальные веса отличаются от решения в Excel. Я получаю массив x: ([3.46944695e-18, 5.00000000e-01, 5.00000000e-01]) в python по сравнению с (правильным) решением в Excel (15%, 73%, 12%). Поэтому я предполагаю, что с оптимизацией должно быть что-то не так, поскольку сама целевая функция кажется правильной. Однако не могу понять, что это может быть.
def objective(w, V, x_t):
vol = ((w*V)*np.transpose(w))[0,0] #Portfolio variance
sig = np.sqrt(vol) #stimmt
risk_target = np.matrix(np.multiply(sig,x_t))
MRC = V*np.transpose(w)
RC = np.multiply(MRC,np.transpose(w))
RC = RC/ sig
RC = (np.multiply(MRC,w.T))/ sig #bis hierhin stimmt alles überein
J = sum(np.square(RC - risk_target.T))[0, 0]
def constraint1(w):
return np.sum(w) - 1
w0 = np.matrix([1/3, 1/3, 1/3]) #initial weights
V = [0.04,0.0015,0.03],[0.0015,0.0025,0.000625],[0.03,0.000625,0.0625] #sample covariance matrix
x_t = [1/3, 1/3, 1/3] # risk budget percent of total portfolio risk
cons = ({"type":"eq", "fun": constraint1}) #constraint 1 that weights add up to 1
b = (0,None) #constraint 2 that weights >= 0
bnds = (b,b,b)
res = minimize(objective, w0, args=(V, x_t), method='SLSQP', bounds=bnds, constraints=cons)
print(res)