Cómo Aumentar la Velocidad de un Backtest

Como todos sabemos, cuando hacemos un backtest tick a tick en MetaTrader4, la velocidad a la que se realiza depende fundamentalmente del número de ticks que haya en la base de datos que utilicemos. Sin embargo, podemos mejorar los tiempos de nuestros backtests gracias a unos pequeños trucos que os voy a contar:
 

1. Ejecutar Backtests en Paralelo

Una forma de acelerar los backtests y a la vez realizar varios de ellos consiste en ejecutar varias instancias de MetaTrader para aprovechar todos los núcleos del procesador (en efecto, si lo estabas pensando… MetaTrader solo aprovecha un núcleo para backtests y optimizaciones).

Para ellos debéis seguir los siguientes pasos:

  • Lo primero de todo debéis mirar cuántos núcleos tiene vuestro procesador. Supongamos que tiene 8 núcleos lo que significa que podréis poner 8 MetaTrader a la vez corriendo backtests y optimizaciones.
  • Creamos 8 copias de nuestra instalación de Metatrader y creamos accesos directos al fichero Terminal.exe (el ejecutable de MetaTrader) con diferentes nombres (MT1, MT2, etc.)
  • Abrimos las 8 instancias haciendo login con la cuenta que deseemos (puede ser la misma o varias diferentes, pero lo recomendable es usar el mismo user y password de una cuenta Live para asegurarnos de que tenemos condiciones reales de mercado). Con esto quedan listas para funcionar las 8 terminales.
  • A continuación debemos descargar e instalar Junction, disponible en https://technet.microsoft.com/en-us/sysinternals/bb896768.aspx. Para instalarlo simplemente debemos descomprimir el archivo descargado en una carpeta que esté en el path del sistema, por ejemplo en C:\Windows\System32\
  • En el siguiente paso debemos averiguar la ruta a la Carpeta de Datos de cada una de las MetaTraders que hemos clonado. Para ello, deberemos arrancarlas una a una e ir al menú File -> Open Data Folder y copiar la ruta completa de la carpeta que tendrá un aspecto similar a este: C:\Users\Usuario\AppData\Roaming\MetaQuotes\Terminal\51CF3DFB510CC5A8F28B58D1BF8A5105\MQL4. Todas las rutas serán similares pero mostrarán pequeñas variaciones al final del churro de letras y números.
  • Una vez apuntadas todas las carpetas, simplemente tenemos que realizar los siguientes pasos para forzar a que todas las MetaTraders usen la carpeta de datos de la MetaTrader nº 1. Para ello primero deberemos eliminar todas las carpetas (excepto la de la primera MetaTrader que no necesitemos abriendo el Símbolo del Sistema de Windows y ejecutando el comando:

    rd /s /q «Carpeta de Datos de la Metatrader nº 2»

    Posteriormente repetiremos el comando cambiando las diferentes carpetas de datos hasta llegar a la de la terminal nº 8.

  • Seguidamente utilizaremos Junction para forzar el uso de la misma carpeta por parte de las Metatrader. Para ello desde la línea de comandos teclearemos:

    junction «Carpeta de Datos de la Metatrader nº 2″ » Carpeta de Datos de la Metatrader nº 1″

    Iremos reemplazando la nº 2 por las siguientes hasta llegar a la nº 8.

Si habéis seguido bien todos estos pasos ya podréis hacer múltiples backtests con vuestra MetaTrader.

Ah muy importante: si también queréis compartir la carpeta de vuestros históricos entre todas las instancias de MetaTrader deberéis repetir un proceso similar al descrito pero usando ahora la carpeta History, de tal forma que la carpeta tendrá la forma: C:\Users\Usuario\AppData\Roaming\MetaQuotes\Terminal\51CF3DFB510CC5A8F28B58D1BF8A5105\history

2. El Impacto del Hardware en los Backtests

Si bien resulta evidente que cuanto más potente sea nuestra máquina, más rápidos serán los backtests y las optimizaciones, lo cierto es que no está de más dar un par de recomendaciones:

  • Por un lado, es altamente recomendable mantener el repositorio de datos de ticks en una unidad de disco SSD. Esto nos dará un extra de velocidad y resultará fundamental de cara a ejecutar backtests u optimizaciones en paralelo.
  • Asimismo, es recomendable con una elevada cantidad de memoria RAM, recomendándose tener al menos unos 2 Gb de RAM por cada instancia ejecutada de MetaTrader 4.

3. Mejorando el Código

En ocasiones nos podremos encontrar con que, a pesar de tener una máquina muy potente los backtests y las optimizaciones siguen siendo muy lentas. En ese caso el problema lo tendremos casi con total seguridad en la falta de optimización del código de nuestro Expert Advisor (EA).

Una buena idea para ver si el problema es del código es realizar un primer tanteo comparando el tiempo que tarda en realizarse un backtest de nuestro EA sobre una base de datos de varios años vs. el tiempo que tarda el MACD Sample EA que viene de serie con MetaTrader. Si bien cabe esperar que un EA complejo tarde más que el MACD Sample EA, lo cierto es que una diferencia de tiempos muy alta puede darnos alguna indicación de si existen problemas.

En todo caso, conviene seguir una serie de recomendaciones para depurar y optimizar nuestro código:

  • Asegúrate de que no haya errores que se repitan sistemáticamente en el log del backtest. Si los hubiera, tome las medidas necesarias para asegurarse de que no se producen.
  • Elimina cualquier referencia a las funciones Comment(), Print() or Alert(). Si por algún motivo, dichas funciones fueran estrictamente necesarias es recomendable deshabilitarlas durante los backtests y optimización no visuales. Para ello podemos usar la variable booleana global isTesting en la función OnInit () tal que:

    isTesting = isOptimization() || (IsTesting() && !IsVisualMode());

  • Por supuesto, tampoco se deben utilizar objetos gráficos durante un backtest. Siendo rigurosos incluso podemos eliminar las flechitas que representan las operaciones en el gráfico cada vez que cambie el número de transacciones usando un código similar al siguiente:

    int orderCount = OrdersTotal();
    if (prevOrderCount != orderCount)
    {
       prevOrderCount = orderCount;
       for(int i = ObjectsTotal() - 1; i >= 0; i--)
       {
          string objectName = ObjectName(i);
          ObjectDelete(0, objectName);
       }
    }

  • Cachea absolutamente todo lo que puedas. Si tenemos funciones que son llamadas varias veces por tick con los mismos parámetros, es mejor almacenar en caché los resultados y devolver los valores almacenados en caché.
  • Adicionalmente, en el caso de algunas estrategias que usen indicadores sólo será necesario realizar todos los cálculos al comienzo de cada barra. Además si usamos indicadores en diferentes timeframes podemos usar el cambio en un timeframe que sirva como común divisor para activar los cálculos (por ejemplo, si usamos indicadores en H1 y M15, no tendremos problema en actualizar todos los cálculos para estos indicadores al inicio de cada barra de 15 minutos).
  • Si queremos ser muy profesionales programando podemos forzar en el código que se omita el procesado de ticks por parte del EA mientras no se den unas condiciones. Por ejemplo, ignorar ticks si el precio está a 5-10 pips del punto de entrada cuando nuestro EA usa objetivos más largos, o activar cálculos cuando el precio se encuentre a una distancia de un determinado nivel de entrada.
  • Normalmente los errores de ejecución de órdenes que se producen cuando ejecutamos nuestro EA en mercado real no suelen aparecer durante los backtests, por lo que de cara a realizar el backtest podemos eliminar tranquilamente las funciones de reintento de lanzamiento de órdenes que hayamos programado. Por ejemplo, llamar a la función IsTradeContextBusy () durante un backtest es completamente inútil.
  • Otra idea muy buena es cargar los valores de todas aquellas variables que sabemos que no van a variar a lo largo del backtest (por ejemplo, los puntos de stop o el número de lotes si es fijo) en el bloque OnInit()
    No revise las órdenes actuales con más frecuencia de la necesaria. Por ejemplo, si nuestro EA tiene una sola posición con un stop ya fijado, no necesita volver a verificar la orden salvo que el stop haya saltado.
  • Finalmente si el EA tiene alguna función almacenada en una DLL (por ejemplo, para proteger derechos de autor), conviene siempre implementar esa función directamente en código MQL en la versión que se utiliza para el backtest o, en su defecto, desactivar todas las comprobaciones de protección suponiendo que seamos los propietarios del código.

Espero que os resulten útiles estos pequeños trucos. Por supuesto, con un poco de imaginación muchos de ellos también pueden adaptarse a otras plataformas como NinjaTrader o TradeStation.

Saludos,
X-Trader

 

COMPARTIR EN: