Esta entrada del blog como sugiere esta respuesta , tiene una implementación bastante completa de una cartera de maximización de rendimiento con riesgo objetivo. La siguiente es una implementación simplificada que escribí para un proyecto anterior, para su referencia. Tenga en cuenta que la construcción de matrices en cvxopt no es totalmente sencilla, y puede tomar algún tiempo para acostumbrarse a la transición de np.
La entrada del blog a la que se hace referencia utiliza la media de las rentabilidades históricas para crear previsiones de rentabilidad, mientras que mi función de abajo toma un vector de rentabilidades como entrada porque he utilizado un método de cálculo diferente para las rentabilidades prospectivas.
import cvxopt as cvx
def markowitz_opt(ret_vec, covar_mat, max_risk):
U,V = np.linalg.eig(covar_mat)
U[U<0] = 0
Usqrt = np.sqrt(U)
A = np.dot(np.diag(Usqrt), V.T)
# Calculating G and h matrix
G1temp = np.zeros((A.shape[0]+1, A.shape[1]))
G1temp[1:, :] = -A
h1temp = np.zeros((A.shape[0]+1, 1))
h1temp[0] = max_risk
ret_c = len(ret_vec)
for i in np.arange(ret_c):
ei = np.zeros((1, ret_c))
ei[0, i] = 1
if i == 0:
G2temp = [cvx.matrix(-ei)]
h2temp = [cvx.matrix(np.zeros((1,1)))]
else:
G2temp += [cvx.matrix(-ei)]
h2temp += [cvx.matrix(np.zeros((1,1)))]
# Construct list of matrices
Ftemp = np.ones((1, ret_c))
F = cvx.matrix(Ftemp)
g = cvx.matrix(np.ones((1,1)))
G = [cvx.matrix(G1temp)] + G2temp
H = [cvx.matrix(h1temp)] + h2temp
# Solce using QCQP
cvx.solvers.options['show_progress'] = False
sol = cvx.solvers.socp(
-cvx.matrix(ret_vec),
Gq=G, hq=H, A=F, b=g)
xsol = np.array(sol['x'])
return xsol, sol['status']