3 votos

Optimización de cartera de varianza media (solo largo) CVXPY incluyendo restricción de cardinalidad

```html

Estoy trabajando en una optimización de cartera que me requiere restringir el número de activos utilizados, por ejemplo del S&P500 construir una cartera de 20 activos que sea factible. Después de hacer algunas investigaciones, llegué a la conclusión de que no hay solucionadores no comerciales disponibles de forma gratuita que puedan manejar problemas mixtos enteros y cuadráticos (probablemente también necesite SOCP). Así que pensé en un paso de preoptimización, es decir, usar un solucionador MIP para obtener esos 20 activos que luego puedo usar en CVXOPT después. O cualquier enfoque heurístico como la programación genética. Tal vez vale la pena mencionar que me gustaría mantenerlo lo más simple posible como primer paso.

Ahora mi pregunta es, ¿alguien tiene experiencia en cómo se implementa esto generalmente? ¿Es el enfoque MIP viable? ¿O puedo hacer algo así como un análisis de PCA primero y elegir los 20 activos no correlacionados principales?

Si la programación entera mixta es el camino a seguir, ¿alguien tiene un ejemplo breve en Python donde pueda tener una idea de cómo se puede implementar?

gracias

EDICIÓN: Implementación de la sugerencia de LASSO de David usando cvxpy

import numpy as np
import cvxpy as cvx

np.random.seed(1)
n = 100

mu = np.abs(np.random.randn(n, 1))
Sigma = np.random.randn(n, n)
Sigma = Sigma.T.dot(Sigma)

w = cvx.Variable(n)
lambda_ = cvx.Parameter(sign="positive")
range_ = np.arange(0,100,1)

ret = mu.T*w
risk = cvx.quad_form(w, Sigma)

objetivo = cvx.Minimize(risk + lambda_*cvx.norm(w,1))
restricciones = [cvx.sum_entries(w) == 1, w >= 0]
prob = cvx.Problem(objetivo, restricciones)

weights_count = []

for lambda_vals in range_:
    print 'Lambda : ',lambda_vals 
    lambda_.value = lambda_vals

    prob.solve(verbose=False)
    print prob.status

    output = []
    for i in range(len(w.value)):
        output.append(round(w[i].value,2))

    weights_count.append(sum(1 for i in output if i > 0))

print weights_count

```

0 votos

¿Has echado un vistazo a este documento y paquete de Python NCVX? arxiv.org/pdf/1601.07277.pdf

4voto

EMP Puntos 17246

En un paso rápido y fácil primer paso podrías agregar regularización $L_1$ al problema de Markowitz. Es decir, añades un término $\lambda ||w||_1$ a la función objetivo de tu problema de optimización (donde $w$ son los pesos de asignación a optimizar).

La regularización $L_1$, que a menudo se denomina LASSO en la comunidad estadística, te dará soluciones dispersas de los vectores de peso, es decir, llevará varios $w_i$ a cero y te dejará con un número seleccionado de pesos de activos restantes. Cuántos activos exactamente permanecerán depende de la elección del parámetro de regularización $\lambda$, que luego deberías ajustar en consecuencia para obtener 20 activos.

Lo bueno de este enfoque es que puedes mantenerte en la misma clase de algoritmos de optimización, porque el valor absoluto de los parámetros puede ser incorporado por restricciones lineales. Ver por ejemplo aquí.

0 votos

Definitivamente voy a intentarlo, lo que terminé haciendo en el intermedio fue lo que hacen otros solucionadores comerciales, por ejemplo, APT resuelven para todo el universo, lo ordenan por peso y truncan esa lista de manera iterativa hasta que alcances tu tamaño de universo objetivo o la última solución factible. No soy un gran fanático de esa solución

1 votos

¿Estás buscando una solución solo para largo? La regularización L1 penalizará las posiciones cortas. ¿Ayudaría a reducir la cardinalidad en las posiciones largas? Alguien sugiere que las regularizaciones de L^{1/2} o L^{p} podrían funcionar mejor para carteras solo largas. También estoy analizando el problema y estaba pensando en implementar algo en python (pero podría comenzar con NCVS). Por favor, házmelo saber si estarías interesado en hacer algo juntos.

0 votos

@Bozothegrey: ¿Puedes explicar por qué la regularización L1 debería penalizar las posiciones cortas? Porque en mi opinión, agregar el término $\lambda || w ||_1$ es indiferente al signo de $w_i$. (Me parece que está allí ya que el artículo también lo menciona, pero ¿por qué? ... realmente no leí el artículo)

Finanhelp.com

FinanHelp es una comunidad para personas con conocimientos de economía y finanzas, o quiere aprender. Puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X