Acceder

Caso práctico de QA para Risk Management

Caso práctico de QA & Risk Management


Buenas queridos amigos, les traigo hoy un ejemplo bien sencillo de risk managemet y su resolución en python

Que es el Risk Managemet y por qué prestarle atención

Siempre digo lo mismo a quienes recién empiezan en el mercado 

Puedes ser muy mal trader, tener muy mal timing, tener mucha mala suerte,  pero no puedes tener mal manejo del riesgo

Por que digo esto?

Simple, si tienes mala suerte muy seguido, tuviste muy mal timing para ciertos activos bien vistos pero muy temprano o muy tarde, o fuiste muy impaciente o arrebatado, pero con buen manejo de riesgo y posiciones, a lo sumo terminaste el año un poco debajo de tu benchmark y simplemente terminarás buscando mejores consejos para mejorar al siguiente año

Ahora, si tienes un mal manejo del riesgo, incluso con mucha suerte, y gran timing, una sola mala jugada, una sola, te puede sacar del mercado para siempre y que termines indignado con la bolsa y no vuelvas mas

A la corta lo importante es el "cuando," y el "que", eso seguro, pero a la larga te puedo asegurar que pesa mas el "cuanto"

De eso se trata el risk managemet, obviamente luego hay que bajar todo a números para parametrizar las estrategias y buscar la cartera que se adapte al inversor y no al revés. Porque si buscamos como inversores adaptarnos a carteras con volatilidades o métricas que no podemos tolerar, lo mas probable es que nos desesperemos y tomemos la peor decisión en el peor momento, y no hay nada mas clave que respetar el plan de inversión fijado


Ejemplo práctico


Supongamos el siguiente caso, tenemos que asesorar a un cliente o amigo que quiere invertir en las empresas TOP de tecnología de USA, no le molesta la volatilidad porque es un inversor a largo plazo no quiere tampoco sacar una rentabilidad anual superior al SP500 pero nos dice que necesita que apliquemos herramientas de análisis cuantitativo para minimizar los drawdowns al mínimo posible manteniendo una rentabilidad similar al SP500

 
Es decir, no le molesta la volatilidad diaria, pero nos dice que no puede soportar un drawdown del 30% como tuvo el SP500 por ejemplo en 2020 con el evento del COVID que hasta un 15% estaría bien, que ideal sería no mas del 10% buscando un CAGR es decir un rendimiento anualizado promedio también cercano o lo mas posible al 10%

 

Calculamos CAGR y Drawdowns del Benchmark y las FAANG


En principio parece muy difícil lo que nos pide pero pensemos un poco, nos dice que quiere invertir en empresas TOP tecnológicas, si vemos el CAGR de esas empresas en los últimos años es altísimo, de hecho vamos a calcularlo:

código para bajar datos y calcular CAGR y drawdowns
código para bajar datos y calcular CAGR y drawdowns

 
Bien, como vemos, el portafolio que armamos con las FAANGs (5 empresas líderes de tecnología que por sus iniciales se las llama FAANG por FB, AMZN, AAPL, NFLX y GOOGL) en los últimos años tuvo un CAGR del 39.16% es enorme! Pero bueno, tuvo un drawdown máximo del 30.9% y ese es el problema que nos piden solucionar minimizándolo

Tenemos una a favor que es que nos dicen que no importa bajar rentabilidad esperada, de hecho nos dan un target del 10% o que no sea inferior al benchmark del SP500, bueno, una primera idea podría ser la siguiente:


El tema del Rebalanceo

Agrego esta aclaración gracias a un lector que me hizo notar que no quedaba claro el tema y es realmente interesante comentarlo

El tema del rebalanceo es muy relevante a la hora de calcular las métricas de los portafolios, hay muchas maneras de calcular las cosas, yo en mi caso particular voy de los simple a lo complejo, por ende empiezo tomando un modelo teórico que rebalancee perfecto, es decir a cada cambio de precio, es como lo hice en el código que puse aquí. Claro está que esta forma de armar un portafolio que rebalancee automaticamente cada día por ejemplo, es muy poco práctico para un inversor individual, los bancos y los institucionales lo hacen pero porque tienen otra estructura y automatizaciones

En el caso nuestro lo mas razonable por practicidad suele ser reblanceos mensuales, quincenales, bimestrales, trimestrales etc, ahora, para calcular es mejor uno bien corto ya que mientras mas corto el reblanceo, mas se elimina el efecto de una sobreponderación por un componente que suba mucho respecto al resto. Por experiencia al pasar de rebalanceos diarios a mensuales no cambia mucho las métricas principales en el agregado de al menos un período anual, aunque si lo hace en el mes puntual, pero como dije, lo ideal es empezar con el rebalanceo mas corto y de ahi a lo mas realista según el caso, el código que puse está preparado para rebalancear automaticamente según el timeframe de la serie, es decir que solo agregando una línea al dataset original con un resample() se pasa a una serie en un timeframe supongamos mensual, y aplicando el mismo código quedan los cálculos con reblanceo mensual.

Planteamos una posible solución a los drawdowns


¿Qué pasa si en vez de tener un portafolio 20% de cada una de las 5 empresas FAANG tuviera un poco menos de cada una y un pequeño porcentaje en el SQQQ (ETF que shortea al Nasdaq es decir que baja cuando el índice sube)? 

Ahí claramente me bajaría la rentabilidad en las subas pero en los momentos de baja me compensaría los drawdowns. Es una idea muy burda, hay maneras mucho mas sofisticadas de resolver el problema, pero me parece ideal por lo fácil para demostrar el poder de Python para resolver estos problemas de forma super sencilla

 
Bueno, pero el problema es ¿hasta donde? Es decir cuanto reduzco la posición en las FAANG para incrementar la posición en SQQQ? Como calculo ese optimo?


Implementamos la solución y la medimos


Para ello nos vamos a apoyar en un pequeño script de Python que vaya aumentando de a 0.1% la posición en el SQQQ y lo que queda lo reparta flat en las FAANGs y me busque el punto óptimo después de llegar a digamos un 40% del SQQQ que ya sería una exageración total.

El script que se me ocurre sería este:

solución en python para mínimo drawdown con igual CAGR que benchmark
solución en python para mínimo drawdown con igual CAGR que benchmark
 

Fíjense que arranca cuando “i” vale 0 con un 0% en el SQQQ, a la siguiente vuelta SQQQ le asigna un peso de 1% y el 99% restante lo divide en 5 partes iguales para cada una de las FAANGs y así hace hasta llegar al 40% para el SQQQ y un 60% para el resto (12% a cada FAANG)

 

Gráfica de resultados de la parametrización de la solución planteada

Al terminar manda este gráfico como salida mi script:

 
gráfica de la parametrización de la solución en python
gráfica de la parametrización de la solución en python
 

O sea que se ve claramente que el CAGR de la estrategia (FAANG+SQQQ línea naranja) va bajando a medida que aumenta la participación del SQQQ en la cartera (es lógico porque fue un período bull para el Nasdaq los últimos 7 años) pero ¿Qué pasa como contrapartida al descenso del CAGR?

Lo que vemos claro es que cuando “i” (eje X, es el número de iteración del ciclo FOR) pasa el número 20, se llega a un techo para el máximo drawdown de la estrategia (FAANg+SQQQ, la línea roja), y mas o menos al mismo tiempo la línea naranja que es la del CAGR de la estrategia como ya dijimos, corta hacia abajo a la línea azul que es el CAGR del benchmark (que obviamente es constante como su máximo drawdown porque no depende de “i”)

Bueno, lo que hay que hacer, respetando la consigna de nuestro cliente es tomar el punto anterior al que la línea naranja cruza para abajo a la azul (como para no estar por debajo del benchmark en el CAGR) y esa sería la combinación óptima de FAANG y SQQQ para minimizar el máximo drawdown manteniendo al menos el mismo CAGR que el benchmark

 

Obtención de solución óptima


El código para obtener ese valor a partir de nuestro dataframe “df” que contenía las 40 simulaciones que hicimos en el ciclo FOR es el siguiente:

KPIs del óptimo
KPIs del óptimo

 

 Como vemos la combinación ideal es un 21% para el SQQQ y un 15.8% para cada una de las FAANGs, eso me da un CAGR del 15.3% que sigue por arriba del 14.6% del SP500 en ese mismo plazo (tome 2013-2020 porque FB no cotizaba antes, si no hubiera tomado un plazo mas largo)

Pero lo importante es que logramos bajar el máximo drawdown a solo un 11.88% 

Es un gran logro manteniendo la rentabilidad, de hecho un CAGR mayor al máximo drawdown hace que tengamos un CALMAR Ratio mayor a 1, lo que es un gran ratio ya que el CALMAR mide el rendimiento compuesto (CAGR) sobre el máximo riesgo asumido (tomando como máximo riesgo al máximo drawdown en todo un período) es decir que si el rendimiento compuesto final, luego de promediar dentro de la serie todos los drawdowns es mayor al máximo drawdown, el CALMAR ratio será mayor a 1 y es un indicador de alguna forma que el máximo dolor soportado es mas que compensado a largo plazo


Reporte de resultados con nuestra solución sugerida implementada 


Bueno, ahora quedaría simplemente mostrarle al cliente la comparación del portafolio que le podemos armar (FAANG 15.8% c/u mas un 21% del SQQQ para contrarestar las bajas) con algunos gráficos de rendimiento pasado de ese portafolio para ver si estaría dispuesto a invertir en el portafolio (entendiendo obviamente que no significa que vaya a pasar lo mismo en el futuro pero que tiene un proxy de como se comporta el portafolio en diversos escenarios)

Para realizar esos gráficos ya que veníamos con la librería quantstats sugiero usar estos gráficos:
 
código python para las 3 gráficas del reporte final
código python para las 3 gráficas del reporte final

 
Que me arroja los siguientes gráficos:
 

EOY - Estrategia vs BenchMark


Comportamiento de la estrategia vs el benchmark año a año (En este gráfico habrá años peores y años mejores, no olvidar que el objetivo no era mejorar rendimiento, de hecho es casi igual apenas superior al SP500) el objetivo era recortar los drawdowns

 

EOY (End of year returns)
EOY (End of year returns)
 

Retornos Acumulados - Estrategia vs Benchmark


Retornos acumulados (En este se ve claramente que el portafolio sugerido (azul) es mucho mas estable y menos volátil y sobre todo no lo afectan las bajadas fuertes es un crecimiento con el mismo final pero un recorrido menos turbulento 

Retornos acumulados Benchmark vs Estrategia
Retornos acumulados Benchmark vs Estrategia
 


Rolling Sharpe - Estrategia vs Benchmark


Rolling Sharpe, que es una medida diferente del riesgo asumido por unidad de retorno lograda.

En este gráfico también se ve claramente como el portafolio armado es mucho mejor que el benchmark ya que el ratio sharpe de la línea azul (portafolio) se encuentra casi siempre por encima de la línea amarilla (benchmark) y de hecho un Sharpe medio de 2 es altisimo, es decir es un portafolio que me da un 2% de rentabilidad por cada 1% de volatilidad asumida. Por lo general es difícil encontrar activos que superen consistentemente un sharpe de 1

Rolling Sharpe, benchmark vs estrategia
Rolling Sharpe, benchmark vs estrategia
 

Por ultimo podemos comparar los drawdowns del benchmark contra los del portafolio sugerido


DrawDowns Underwater Plots - Estrategia vs Benchmark


Primero el banchmark, peores momentos en 8 años:

·        1 vez abajo del -30%
·        1 vez en -20%
·        2 veces en -12% aprox
·        2 veces en -10% aprox

drawdowns del benchmark
drawdowns del benchmark
 


Y ahora el portafolio
 
drawdowns de la estrategia
drawdowns de la estrategia

 

Ojo que no confunda que cambio la escala del gráfico este gráfico tiene escala entre 0 y -12% ya que no hubo DD inferiores a -12% en todo el período

Peores momentos en 8 años:

·        1 vez en -12%
·        2 veces en -10%


Código para visualizar ambos drawdowns juntos

A veces el uso de librerías como quantstats está muy bueno porque con muy pocas líneas nos simplifica mucho la vida, pero también hay veces que queremos ver otras cosas en donde la librería ya no nos alcanza y tenemos que codear a mano, en este caso yo quería mostrar los dos drawdowns la serie histórica superpuestos en la misma escala y la librería no tiene un método para ello, así que no me quedó otra que construir el gráfico "a mano" que de todos modos con matplotlib y pandas es muy sencillo hacerlo, se los muestro:

drawdowns superpuestos en misma escala
drawdowns superpuestos en misma escala

 


Conclusiones

En primer lugar un mini disclaimer que es el mismo de siempre, pasado no garantiza futuro, es decir, que nuestra prueba haya funcionado los últimos 8 años no significa que en el futuro lo siga haciendo, es decir las FAANGs en los próximos 8 años pueden rendir mucho menos que el SP y no darme ni ahí ese CAGR, seguro, pero la compensación con el SQQQ de los drawdowns va a seguir operando del mismo modo ya que en momentos críticos del mercado va a compensar esos drawdowns pero me va a quitar rentabilidad en los momentos bullish

Una segunda aclaración es que una forma mas profesional de atacar los drawdowns es con  estrategias armadas con puts comprados en los momentos de baja volatilidad con posibilidad de alza o con calls vendidos en los momentos de alta volatilidad en baja, pero son análisis mas complejos que el alcance de este humilde blog de difusión general

El punto central es que partíamos de la base de una buena idea inicial pero con "drawdowns" o volatilidades o lo que fuera que no podíamos pasar y armamos una cartera alternativa modificando a la original para justamente neutralizar hasta un punto "aceptable y conveniente" esas métricas que no nos convencían, de eso se trata el risk management ya que cuando nos enfrentamos a situaciones muy adversas que no podemos tolerar psicológicamente, terminamos vendiendo en el peor momento simplemente por enfrentarnos a un escenario que sabíamos de entrada que no íbamos a tolerar, pero eso lo podemos evitar justamente armando carteras que sabemos que no nos van a exponer a esas situaciones, o al menos, está bíen, no lo sabemos, pero tenemos menos probabilidad de que sucedan porque están estructuradas para minimizar esas situaciones, obviamente siempre con la contrapartida de resignar rentabilidad esperada, "there is not free lunch" nunca olvidemos eso



3
¿Te ha gustado mi artículo?
Si quieres saber más y estar al día de mis reflexiones, suscríbete a mi blog y sé el primero en recibir las nuevas publicaciones en tu correo electrónico
  1. #3
    Cadenaperpetua
    17/02/21 13:11
    Con que editor ejecutas quantstats? con idle y con vs code no me va.
    no consigo que quantstats me grafique, me tira 2 errores:
    1- la linea % matplotlib inline o %matplotlib inline me da siempre error
    2-File "c:\Users\Desktop\TRABAJOACTUALBACKUP\crearinformequantstats.py", line 50, in <module>
        qs.reports.html(df, "SPY")
      File "C:\Users\AppData\Local\Programs\Python\Python39\lib\site-packages\quantstats\reports.py", line 47, in html
        raise ValueError("`file` must be specified")

    Saludos y gracias de antemano


  2. en respuesta a Cadenaperpetua
    -
    #2
    10/12/20 23:09
    Hola, gracias por el feedback, si está rebalanceado diariamente, voy a agregar la aclaración porque no estaba explicado ese detalle, pero es así, en el cálculo de los rendimientos uso una ponderación los weights ("w" llamo a la variable) que multiplican matricialmente a todo el dataset, que como está en un timeframe diario termina siendo como un rebalanceo diario, es teórico el ejercicio porque es raro rebalanceos diarios, excepto fondos e institucionales, pero resampleando el dataset a cualquier timeframe diferente se adapta el rebalanceo de las ponderaciones al timeframe tomado, es lo bueno del enfoque matricial para resolver estos ejercicios
  3. #1
    Cadenaperpetua
    10/12/20 18:40
    Hombre yo lo que veo alli sin conocer la libreria quantstats, es que el % que metes a las Fang y al etf inverso QQQ, se lo metes el año de inicio de la inversion, con lo cual pasados los años al no haber rebalanceo(o yo por lo menos no lo he visto en el código), realmente esos % ya no son los que eran. Para ser asumible esa estrategia en el tiempo, se deberia rebalancear, cada año o bien cuando los % varien un10% por decir algo.

    Ya te digo que todo esto lo digo sin tener mucha idea y menos de quantstats. 

    Muy buen articulo, si bien lo veo demasiado avanzado, en cuanto a programación que no a concepto, para la mayoria del personal que poblamos rankia