Encontré este código en el sitio plotly, utilizando CVXOPT para encontrar la frontera eficiente y luego la cartera óptima. La función óptima es
def optimal_portfolio(returns):
n = len(returns)
returns = np.asmatrix(returns)
N = 100
mus = [10**(5.0 * t/N - 1.0) for t in range(N)]
# Convertir a matrices cvxopt
S = opt.matrix(np.cov(returns))
pbar = opt.matrix(np.mean(returns, axis=1))
# Crear matrices de restricción
G = -opt.matrix(np.eye(n)) # matriz identidad negativa de n x n
h = opt.matrix(0.0, (n ,1))
A = opt.matrix(1.0, (1, n))
b = opt.matrix(1.0)
# Calcular los pesos de la frontera eficiente usando programación cuadrática
portfolios = [solvers.qp(mu*S, -pbar, G, h, A, b)['x']
for mu in mus]
## CALCULAR RIESGOS Y RETORNOS PARA LA FRONTERA
returns = [blas.dot(pbar, x) for x in portfolios]
risks = [np.sqrt(blas.dot(x, S*x)) for x in portfolios]
## CALCULAR EL POLINOMIO DE 2º GRADO DE LA CURVA DE LA FRONTERA
m1 = np.polyfit(returns, risks, 2)
x1 = np.sqrt(m1[2] / m1[0])
# CALCULAR LA CARTERA ÓPTIMA
wt = solvers.qp(opt.matrix(x1 * S), -pbar, G, h, A, b)['x']
return np.asarray(wt), returns, risks
weights, returns, risks = optimal_portfolio(return_vec)
Mi pregunta se refiere a las líneas donde el código ajusta una parábola a la frontera eficiente
m1 = np.polyfit(returns, risks, 2)
toma la raíz cuadrada de la división de la intercepción por el coeficiente de x al cuadrado
x1 = np.sqrt(m1[2] / m1[0])
y lo pone en la optimización
t = solvers.qp(opt.matrix(x1 * S), -pbar, G, h, A, b)['x']
¿Alguien puede explicar por qué se hace esto?
¡Gracias!
1 votos
Deberías estudiar las matemáticas para derivar la frontera de media-varianza (Hay versiones por todos lados, pero aquí tienes un ejemplo.) Luego verifica si lo que están resolviendo es correcto o tiene sentido. Para las carteras en la frontera, la varianza del rendimiento de la cartera es cuadrática respecto al retorno esperado (por lo que asumo que están ajustando un polinomio de 2do grado).