Мне нужно найти Портфолио с минимальной дисперсией, используя scipy optimize.У меня есть следующая ковариационная матрица:
[[0.00076593 0.00087803 0.00082423 0.00094616 0.00090782]
[0.00087803 0.0015638 0.00086395 0.00097013 0.00107642]
[0.00082423 0.00086395 0.00092068 0.00104474 0.00099357]
[0.00094616 0.00097013 0.00104474 0.00133651 0.00119894]
[0.00090782 0.00107642 0.00099357 0.00119894 0.00132278]]]
И первоначальное предположение для весов портфеля:
[0.2,0.2,0.2,0.2,0.2]
Выполнение следующего кода, где V - ковариационная матрица сверху:
import pandas as pd
import numpy as np
from scipy.optimize import minimize
from tqdm import tqdm
#Minimum Variance
cov_rol = df_smartbeta.rolling(window=36).cov()
cov_rol = cov_rol.values.reshape(665,5,5)
V = cov_rol
def objective(w, V): #portfolio variance, 1x1 array
w1= np.matrix(w)
wt = np.matrix(w1)
wt = np.transpose(wt)
return (w1*V)*wt
def constraint1(x): #constraint 1: sum w0 = 1
return np.sum(x)-1
w0 = np.array([0.2,0.2,0.2,0.2,0.2]) #initial guess
cons = ({"type":"eq", "fun": constraint1}) #merge constraints
b = (0,None) #define bounds. Lower bound: 0. Upper bound: None
bnds = (b,b,b,b,b)
count = 0
w_min = []
for i in tqdm(range(len(cov_rol))):
res =minimize(objective, w0, args=(V[count]), method="SLSQP",bounds=bnds, constraints=cons)
w_min.append(res.x)
count += 1
w_min_dataframe = pd.DataFrame(w_min)
Код просто возвращает первоначальное предположение, хотя он должен дать
[1.0,0,0,0,0]
Если я масштабирую ковариационную матрицу путем умножения на 100, код работает.Кто-нибудь знает, почему это происходит и как решить проблему без масштабирования?Я уже видел несколько похожих вопросов, но не нашел ни одного решения, которое работает ...