Skipy.optimize - Как установить ограничения в оптимизации портфеля так, чтобы каждый элемент в векторе был идентичен? - PullRequest
0 голосов
/ 15 января 2019

Я создаю паритетный портфель риска, в котором вклад риска («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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...