Captura de pantalla 2023 06 07 a las 15.27.31
 Martí Castany es Quant Researcher, Co- Fundador y Portfolio Manager de KomaLogic, una pequeña firma de trading sistemático. Tiene más de 8 años de experiencia trabajando en el desarrollo de modelos cuantitativos y como consultor en el sector de la gestión de riesgos para el buy y el sell side.
Martí Castany / kjtradingsystems.com

 

  • Si eres un trader sistemático que quiere automatizar su operativa, poder hacer un backtest de calidad de tu estrategia será un paso fundamental antes de ponerla a operar con una cuenta de trading real.
  • Artículo publicado en Hispatrading 54.

En este artículo, pretendo explicarte de manera general cómo estructurar tu proceso de backtesting para que puedas llevarlo a cabo con las máximas garantías. Pero antes de entrar en materia, conviene tener claro qué es un backtest y para qué sirve. Voy a ser lo más claro y conciso que pueda:

Un backtest es el proceso de poner a prueba una estrategia de trading utilizando datos históricos y sirve para evaluar tanto la hipótesis de la estrategia como su desempeño en el pasado.

Es decir, utilizamos el backtesting para ver cómo se hubiera comportado una estrategia de trading durante los últimos 10 años (por ejemplo) y sacamos conclusiones de ello.

pastedGraphic.png
Figura 1. Backtest IS, OOS y operativa real.

Suena sencillo, y en esencia lo es. Sin embargo, hay variables que se deben tener en cuenta para poder garantizar la validez de este proceso, dado que hay una multitud de errores en los que podríamos caer sin darnos cuenta que arruinarían la validez estadística de dicha prueba y de las conclusiones que podríamos sacar de ella.

Lo primero que vas a necesitar será una plataforma que disponga de un buen motor de backtest.

Plataforma

La mayoría de las plataformas comerciales cuentan con un motor propio de backtest, por lo que, normalmente, la opción más sencilla es utilizar el que viene por defecto. Cada plataforma tiene también su propio lenguaje de programación con el que deberás haber codificado tu estrategia, de manera que también determinará en gran medida toda tu infraestructura tecnológica. Te comparto los casos más típicos:

  • MetaTrader 4 & 5: MQL4 & MQL5
  • CTrader: C#
  • TradeStation: EasyLanguage
  • MultiCharts: C++, C#, VB.NET, EasyLanguage
  • NinjaTrader: NinjaScript (una extensión de C#)
  • ProRealTime: ProBuilder

Evidentemente, también existe la opción de crear un motor personalizado si las plataformas anteriores no pueden cumplir con tus necesidades. Si este fuera el caso, te comparto también algunos buenos frameworks para crear tu propio software de backtesting en Python:

  • Backtrader
  • Backtesting.py
  • Zipline
  • PyAlgoTrade
  • QSTrader

Conocer bien el motor de backtest es importante porque cada motor tiene sus propias características y las debes tener en cuenta para que el resultado del backtest emule lo mejor posible el comportamiento que hubiera tenido la estrategia en la realidad.

Para ponerte un ejemplo, el motor de backtest de la plataforma MT5 procesa absolutamente todos los ticks que tiene tu set de datos, algo que no tendría por qué ocurrir durante el trading a tiempo real, ya que si llega un nuevo precio del mercado pero tu estrategia aún está procesando el anterior, éste nuevo tick se ignorará. Este ejemplo en concreto puede no parecer muy importante, pero si quieres que tus backtest sean lo más precisos posible, deberás tener en cuenta este tipo de detalles.

En este caso, tendrías que introducir en tu estrategia un código de control de ejecución que garantizara que la manera de procesar los ticks a tiempo real y en el backtest fueran exactamente las mismas. Este es un problema fácil de solucionar: simplemente ejecuta tu código en el primer tick de cada vela. Sin embargo, esto sólo tiene sentido si trabajas con velas japonesas (o cualquier otra forma de agregación por tiempo). Si trabajas con datos tick a tick, este problema se vuelve más complejo de solucionar: debes estimar el tiempo de ejecución de tu código para cada nuevo tick y verificar si a la hora de llegada de cada nueva cotización, tu programa ya se habría ejecutado y estaría libre para volver a hacerlo.

Por ahora, doy por hecho que ya tienes tu motor de backtest elegido y estudiado, así como tu estrategia programada en el lenguaje que tu plataforma necesita. Pasemos entonces al siguiente aspecto a tener en cuenta: los datos históricos.

Datos de calidad

Para realizar un backtest correctamente es esencial disponer de los datos históricos de los activos sobre los que quieres evaluar tu estrategia. Tal y como comentaba antes, el objetivo del backtest es el de poder evaluar los resultados de una estrategia en el pasado, por lo que disponer de datos históricos de calidad es de vital importancia. Nótese el énfasis en la palabra calidad. Los datos históricos son la materia prima del backtest, por lo que datos con errores nos llevarán a backtests con errores y, de manera irremediable, llegaremos también a conclusiones con errores. Creo que ya entiendes por dónde voy.

Cuando hablo de datos históricos de calidad, me refiero a datos precisos y fidedignos, que representen con la máxima veracidad lo que realmente ocurrió en el pasado y que estén libres de errores. Y quizás podrías pensar: ¿los datos históricos que hay disponibles tienen errores? Yo mismo cometí el error de creer que los datos históricos que podía obtener de una institución o un broker ya serían de calidad, pero me llevé una agradable sorpresa (nótese la ironía) al descubrir que no podía estar más equivocado. De aquí surgió un primer principio:

Revisa y analiza siempre los datos históricos, independientemente de lo reputada que pueda ser su fuente, antes de utilizarlos en tu backtest.”

De manera que no basta con descargar los datos, sino que hay que revisarlos y, quizás, transformarlos. No es lo mismo descargar datos tick a tick que descargar datos con temporalidades ya definidas como podrían ser los precios de cierre de cada hora o de cada día.

Los dos puntos más críticos a revisar sobre la calidad de los datos son los siguientes:

  • Presencia de spikes: un spike es un cambio repentino de precio fruto de un error en la captura de los datos. Por ejemplo, el precio de AAPL es de $153 el día 1, de $8624 el día 2, y de $154 el día 3. Como ves, en el día 2 ha habido una anomalía en forma de spike.
  • Presencia de valores nulos: en tu archivo de datos que te has descargado de Yahoo Finance, podría ser que justamente no tuvieras datos disponibles del precio de cierre de AAPL del día 8 de junio. Una manera de solucionarlo es buscar ese precio en concreto en otro proveedor de datos, como Investing o Google Finance.

Si desconoces que tus datos contienen errores de este tipo, creo que puedes imaginarte la magnitud de afectación que podrían tener a los resultados de tu backtest.

Rangos de datos

En este punto, tenemos nuestra estrategia preparada y un histórico de calidad. Pero antes de poder lanzar el backtest, nos falta un último punto: definir los rangos de datos que vamos a utilizar.

La primera pregunta que te puede venir a la cabeza es: ¿Debería usar todos los datos que tengo disponibles para realizar el backtest, por ejemplo desde 2010 hasta la actualidad? Al contrario de lo que pueda parecer, que cuantos más datos históricos uses mejor, la respuesta es NO.

Deberás separar el conjunto de datos históricos en dos grupos conocidos como In Sample y Out Of Sample (a partir de ahora me referiré a ellos como IS y OOS), cumpliendo cada uno de ellos una función específica y determinante dentro del backtest.

En los datos IS es donde llevarás a cabo el entrenamiento de la estrategia: comprobarás que la estrategia funciona correctamente (por ejemplo, si entra y sale del mercado cuando debe), evaluarás si arroja beneficios o pérdidas, realizarás los ajustes pertinentes si fuera necesario, y optimizarás la ponderación de las distintas variables para capturar de manera óptima el comportamiento del precio que quieres explotar.

Por el otro lado, en el rango de datos OOS harás la verificación de la estrategia: comprobar que el rendimiento que la estrategia tenía en los datos IS se mantiene durante los OOS. Aquí no deberás hacer ningún ajuste de los parámetros, ya que van a ser unos datos nuevos que tu sistema no habrá visto antes, y esa es la razón por la que la verificación tendrá validez. Sería el equivalente a lanzar la estrategia a tiempo real pero sin tener que esperar a que pasen los días, meses o años.

Este punto es extremadamente importante ya que es donde deberás evaluar si tu estrategia ha sido sobreoptimizada, un problema potencialmente peligroso conocido también como data-snooping bias u overfitting. Esto ocurre cuando se busca exhaustivamente cualquier combinación de variables que exprima al máximo las capacidades del sistema, queriendo optimizar tanto los parámetros de la estrategia en referencia a los datos usados durante el backtest (datos IS), que lo que se está haciendo realmente es forzar la estrategia para que obtenga los mejores resultados solamente en ese preciso rango de datos. Las probabilidades de que esas exactas condiciones se repitan en el futuro son prácticamente nulas, de manera que ese sistema que parece tan fiable y que gana siempre y mucho, una vez puesto a trabajar a tiempo real será una máquina de perder dinero. En un vocabulario más técnico, lo que ha pasado realmente es que el sistema ha modelado el propio ruido de los datos. 

Desafortunadamente es muy complicado poder asegurar que la estrategia está libre al 100% de este problema, ya que los resultados podrían ser, sencillamente, fruto de la suerte. Por este motivo es tan importante realizar la verificación del sistema de trading utilizando los datos OOS. Si la estrategia está libre de overfitting, verás que se comporta de una manera similar a la que lo hacía en los datos IS. Esto reduce considerablemente la probabilidad de sufrir de sobreoptimización y es una primera muestra de robustez.

Es imprescindible que si la estrategia arroja buenos resultados durante el período IS pero no en el OOS, no toques sus parámetros para hacer que también arroje buenos resultados en el período OOS. Si lo hicieras, estarías optimizándola de nuevo y habrías convertido los datos OOS en parte de los IS, manipulando los resultados y eliminando su validez. En otras palabras, solo tienes una oportunidad para probar la estrategia en los datos OOS y mantener su integridad.

Como norma general, utilizo el 66% de los datos para entrenar la estrategia (IS) y el 33% restante para verificarla (datos OOS). Es decir, si tengo 20 años de datos disponibles, utilizo aproximadamente 13 años como periodo IS y 7 como periodo OOS.

Costes de transacción

Finalmente, vamos a prestar especial atención a los costes de transacción. Éstos son todos los costes que van implícitos cuando realizas una operación en el mercado. Deberás incluirlos en el backtest, ya que serán costes reales que van a existir durante la operativa.

El más común es la propia comisión que carga el bróker por cada operación. Esta comisión suele ir en función del volumen operado (número de acciones, contratos, lotes). Por ejemplo, con una comisión de 5$ por contrato ida y vuelta o roundtrip (2,5$ para entrar y 2,5$ para salir del mercado), una operación de 20 contratos te costará 100$, mientras que una de 2 contratos te costará 10$.

También existen otros costes indirectos que afectan a la operativa, como son el spread, el slippage y el swap. 

El spread es la diferencia entre el precio de compra (ask) y el precio de venta (bid). Cuando realizas una transacción, siempre está comprendida por una compra y una venta (o viceversa). Esa diferencia entre el precio bid y el ask se convierte en un coste para ti si tus entradas y salidas son “a mercado”, es decir, consumiendo liquidez del libro de órdenes. Podrías reducir el coste del spread utilizando órdenes límite (en mercados que no sean de CFDs), aunque con el riesgo de que no se activen.

Otro coste indirecto es el slippage. Este ocurre en mayor magnitud durante momentos de alta volatilidad o poca liquidez, cuando el precio se mueve rápidamente arrastrando la orden de entrada y ejecutándola a un precio distinto al que tu estrategia tenía predefinido. El slippage puede producirse tanto en la entrada como en la salida y jugar tanto a favor como en contra, aunque lo más habitual es que sea en contra (qué sorpresa). Por esta razón lo consideramos como un coste en la operativa.

Finalmente, en el caso de los CFDs y las divisas, el swap o rollover es el coste que tiene mantener una posición abierta durante la noche. El coste en sí es el rollover, y viene determinado por el swap, que es el diferencial entre los tipos de interés de las distintas divisas que conforman un par (por ejemplo el euro y el dólares en EURUSD).

Conclusión

Como habrás podido comprobar, el backtesting es un proceso delicado que requiere de mucha atención en cada uno de sus pasos para poder garantizar su veracidad. Si quieres tener éxito como trader algorítmico, es imprescindible que tu proceso de backtesting sea lo más riguroso posible para que puedas tener la confianza necesaria para ponerla a trabajar con capital real.

Si tienes cualquier duda o te gustaría saber más acerca del proceso de codificación y backtesting de una estrategia sistemática, puedes ponerte en contacto conmigo a través del formulario de contacto que encontrarás en la parte inferior de la web de KomaLogic.com.