Trading con Python #8 - Tu primer backtest
En este número vamos a hacer un pequeño backtest, por fin hemos llegado a la parte más importante de esta serie de publicaciones. Como este número es muy extenso y denso, te pido que prestes especial atención y lo repitas tantas veces como necesites.
Esas líneas iniciales ya deberían estar claras. Primero las lineas para importar, en este caso importaremos pandas y numpy, y luego importamos los datos.
Estas líneas de código calculan las dos medias móviles que vamos a utilizar para la simulación. Como ves, solo hacen referencia a una ventana de tiempo móvil de 50 y 100 filas respectivamente, y calculan una media de ellas.
La siguiente línea comprueba qué días deberíamos ser largos y qué días deberíamos ser planos. La estrategia es que seremos largos si la media móvil más rápida está por encima de la más lenta. Es decir, cuando la columna SMA50 esté por encima de SMA100, estaremos largos. De lo contrario, vamos a estar en liquidez ('flat').
Lo que hace la línea anterior es establecer la columna Position en 1, donde SMA50 es más alto que SMA100, y establecer todos los demás días como 0.
Pero aquí hay una parte importante en términos de lógica. En este punto del código, la columna de posición cambia el mismo día en que se cruza el promedio. Es decir, comerciamos instantáneamente al precio de cierre, el mismo valor en el que basamos nuestro cálculo promedio y, por lo tanto, nuestra señal. Eso es claramente una trampa. Para que esto sea incluso razonablemente justo, tenemos que retrasar la operación hasta el día siguiente a la señal. Por suerte, esto se hace muy fácilmente.
A continuación, calculamos cuánto porcentaje al día cambia la estrategia. Esto es fácil, si lo piensas. Sabemos cuánto porcentaje se mueve el activo al día. Y sabemos que estaremos largos el 100 % del índice si la media móvil de 50 días está por encima de los 100. Si ese no es el caso, afecta a nuestro balance.
Tomamos el cambio porcentual diario del activo y lo multiplicamos por la columna Position que acabamos de crear. Recuerda que esta columna será 1 si deberíamos estar largos, de lo contrario 0.
Observa lo fácil que puedes obtener el porcentaje de rendimiento del activo. Solo nos referimos a esa columna en nuestro Pandas DataFrame y llamamos a la función pct_change() .
A continuación, es hora de calcular el rendimiento de nuestra estrategia. Ya conocemos los números de devolución diarios, y solo tenemos que hacer una serie temporal a partir de ellos. La forma más sencilla sería añadir el número 1 a todos los rendimientos porcentuales y, a continuación, usar la función de Pandas cumprod(). Esto calculará el producto acumulativo de la serie.
Ten en cuenta en la línea de código anterior que podemos añadir un número a cada fila de la columna, simplemente utilizando el signo más. Otros lenguajes de programación se quejarían de que estamos mezclando conceptos, tratando de añadir un número estático a una lista de números. Pero los Pandas descubrirán lo que queremos decir y añadirán el número a cada fila.
Importante
Sería útil trazar la alternativa de Buy&Hold, junto a la estrategia, para que podamos comparar las dos. El método aquí es el mismo que cuando calculamos los rendimientos de la estrategia, solo lo basamos en las series temporales reales del activo.
Por último, la última linea de código, ploteamos las dos líneas. Lo que nos importa aquí es mostrar la curva de capital de nuestra estrategia junto al punto de referencia de Buy&Hold, y eso es lo que hace esto.
Acabas de hacer tu primer backtest de Python. ¡Enhorabuena!
Otros activos
Esta estrategia vemos que no es muy positiva, pero vamos a cambiar el activo por otro que se comporta mejor con esta estrategia, la URL es esta:
http://czr.es/csv/czr/SP500.csv
A destacar en este backtest, que la nuestra estrategia estaría en liquidez en esta última caída. Aún así, la conclusión es que un cruce de medias no siempre mejora al Buy&Hold, dependerá de muchos factores: del activo, de la temporalidad, de los periodos de la media, etc... y no olvidemos que quizás nos interese sumar menos beneficio, si el drawdown es menor ya que así podremos combinarlo con otras estrategias, pero es ya es tema para otras ediciones de la newsletter.
Ejercicios
Te envío este número en sábado para que tengas tiempo, ya que te pongo deberes, debes buscar datos de otros activos, dependerá de la fuente de donde los consigas, puede que las columnas no se llamen igual que las de mi ejemplo, experimenta con ello, puede que las fechas estén en otro formato, experimenta con ello, prueba otras medias, haz mil pruebas.