La optimización de cartera de Mean-Variance ha atraído mucha atención en este foro hasta ahora. Estoy interesado en el efecto de incorporar costos de transacción en el marco de decisión y me gustaría obtener carteras 'óptimas'. En otras palabras, los enfoques que aún son capaces de ser resueltos utilizando programación cuadrática al restringir el máximo turnover no son lo que busco. Recientemente, esta pregunta fue resuelta con la ayuda de la comunidad con el fin de obtener carteras óptimas si consideramos costos de transacción cuadráticos. Sin embargo, ¿qué sucede si consideramos costos de transacción en forma de "V", lo que significa que pagamos una tarifa en relación a la suma de reequilibrio absoluto: $$TC(\omega_\text{new}) \propto ||\omega_\text{new}-\omega_\text{old}||.$$ Este (bastante viejo) artículo de Atsushi Yoshimoto aborda exactamente el problema de optimización que quiero resolver: $$ \omega_\text{new} = \arg\max {\omega'\mu - \sum_{i=1}^N c_i -\lambda \omega'\Sigma\omega} \\ \text{s.t.} c_i = k(d^+ _{i,t} + d^- _{i,t}), \forall i \\ \omega_{i}-\omega_{old} = d_{i} ^+ - d_{i} ^-, \forall i \\ d_i ^+ d_i ^- =0, \forall i \\ d_i ^+, d_i ^- \geq 0 \forall i \\\omega'\iota=1 $$ Intuitivamente, la optimización está haciendo lo siguiente: Dadas estimaciones de retornos futuros $\mu$ y volatilidad $\Sigma$, buscamos $\omega$ que maximice nuestro equivalente de certidumbre. Este valor disminuye con los costos totales de transacción $\sum c$. Los costos de transacción ocurren si reequilibramos nuestra cartera: Dado que aumentamos la participación de la riqueza en un activo $i$, esto afecta a $d_i ^+$ y, viceversa, si disminuimos la participación de la riqueza en un activo, esto aumenta $d_i ^-$. El reequilibrio total en el activo $i$ es por lo tanto $d_i ^+ +d_i ^-$. La restricción $d_i ^+ d_i ^- = 0$ asegura que no se puede comprar y vender simultáneamente un activo (lo que debería ser claro). La última restricción requiere que nuestros nuevos pesos de la cartera $\omega$ sumen 1, por lo tanto estamos invirtiendo todo el dinero en los activos disponibles (no incorporé una restricción adicional de venta en corto aquí, a diferencia de Yoshimoto).
Me encantaría implementar esta optimización en R, Matlab, Python, lo que sea, pero no comprendo la estructura explicada en este artículo: Todo lo que se explica es que se utilizó un optimizador no lineal llamado GAMS/MINOS. Creo que, 20 años después de su publicación, debería haber ciertamente un enfoque públicamente disponible para hacer esto, por lo tanto pregunto (i) ¿existe ya una implementación? (ii) Si no, ¿cómo hacer esto correctamente?
EDIT: Para mostrar mi primer enfoque trabajé en este pequeño ejemplo para R. Aquí descarto la estimación de la media y solo considero el tiempo de volatilidad:
library(alabama)
library(quantmod)
symbols <- c("MSFT","AAPL","MMM")
getSymbols(symbols,src='yahoo',from = '1995-01-01')
N <- length(symbols)
MSFT <- to.monthly(MSFT)
AAPL <- to.monthly(AAPL)
MMM <- to.monthly(MMM)
returns <- data.frame(MSFT=diff(log(MSFT$MSFT.Adjusted)),
AAPL=diff(log(AAPL$AAPL.Adjusted)),
MMM=diff(log(MMM$MMM.Adjusted)))
returns <- na.omit(returns)
names(returns) <- symbols
mu <- rep(1,N)
sigma <- cov(returns)
lambda <- 4
costpara <- 50/10000
wold <- rep(1/N,N)
fn <- function(w) -w%*%mu + costpara*sum(abs(w- wold))+lambda*t(w)%*%sigma%*%w
heq <- function(w) return(sum(w)-1)
out <- constrOptim.nl(par=wold, fn=fn,heq=heq)
rbind(out$par,wold)
wnew 0.3333233 0.08347908 0.5831977
wold 0.3333333 0.33333333 0.3333333
Sin embargo, no estoy muy familiarizado con la optimización numérica, ¿puede alguien confirmar que este enfoque es correcto, o señalar formas de mejorar la optimización?
0 votos
No entiendo cómo resolviste realmente el problema del costo de transacción: en tu código, estableces
costpara = 50/10000
, pero esto debería depender de tu solución óptima final, por lo que parece que resolviste tu problema haciéndolo constante.0 votos
Gracias @JejeBelfort. De hecho, la descripción puede ser algo vaga: Lo que asumo implícitamente es que los costos de transacción son proporcionales a la cantidad de rebalanceo $||w_\text{new} - w_\text{old}||$ con una constante fija de proporcionalidad de 50 puntos base. Este parámetro está fijo ad hoc y determina los costos condicionales a los pesos.
0 votos
¡Gracias por la precisión @muffin1974! En realidad, estoy tratando de formular este problema en uno de programación cuadrática para resolverlo usando
cvxopt
en python, pero no sé cómo manejar las variables mudas $d_{i}^+$ y $d_{i}^-$ en el problema de optimización (¡ni siquiera estoy seguro si esto es matemáticamente posible!). ¿Sabes dónde puedo encontrar algo de código en python para lograr lo que hiciste?0 votos
¡Gracias @JejeBelfort! No estoy al tanto de un paquete de Python, pero puedo referir (en un acto descarado de autopromoción) a este artículo en el que mostramos que la penalización de rotación tipo L1 y L2 se puede incorporar a través de una optimización penalizada estándar tipo Lasso o Ridge para la cual creo que métodos estándar en Python deberían existir (para la penalización de L2, de todos modos, hay una solución en forma cerrada). ¡Espero que esto ayude!