Python para backtesting forex — stack, ciclo y advertencias honestas

Última verificación: · Contenido de vigencia prolongada
Advertencia de riesgo · YMYL Este artículo tiene fines exclusivamente educativos y no constituye asesoramiento de inversión. Operar en el mercado Forex conlleva un alto riesgo de pérdida de capital — la ESMA informa que entre el 74 % y el 89 % de las cuentas minoristas pierde dinero.

El probador de estrategias de MT5 funciona bien mientras tu estrategia encaja en sus supuestos: reglas de entrada simples, un instrumento, sin conexiones de datos complejas. En cuanto quieres combinar varias fuentes, cruzar señales de varios pares o calcular el ratio de Sharpe junto a la distribución del drawdown (caída máxima), la herramienta se queda corta. Por eso la comunidad sistemática lleva años haciendo sus pruebas retrospectivas en Python. Las razones son claras: control total de las reglas, librerías de calidad científica, cualquier fuente de datos dentro de un solo script y un ciclo de investigación donde el tiempo entre la idea y la curva de capital se reduce a minutos.

¿Por qué los traders dan el salto más allá del Strategy Tester?

El Strategy Tester está bien optimizando un expert advisor en un par y un marco temporal — y ahí se detiene. En cuanto mezclas datos externos al bróker, combinas varios pares en una sola señal o calculas un ratio de Sharpe junto a la distribución del drawdown, acabas pegando archivos CSV en Excel. Python condensa ese trabajo en un solo script: las cotizaciones del bróker entran en pandas, los datos macro se añaden con el mismo merge y las métricas de riesgo vienen de librerías académicas. El contexto completo de la automatización está en nuestra guía de primeros pasos en el trading algorítmico; la comparativa entre MetaQuotes y Python se desarrolla en el artículo sobre MQL5 frente a bots en Python.

El stack práctico

El stack es conciso. El manejo de datos reside en pandas y numpy: el primero gestiona la serie temporal y el resampling de M1 a H1; el segundo proporciona la aritmética vectorizada bajo los indicadores. El motor de backtesting (prueba retrospectiva) es habitualmente backtrader, de Daniel Rodriguez, con su arquitectura event-driven de clases Strategy y Cerebro, o vectorbt, de Oleg Polakov, cuando necesitas explorar cientos de combinaciones de parámetros en decenas de segundos. Los gráficos llegan de matplotlib para informes estáticos y de plotly para revisión interactiva. Los datos históricos entran por yfinance para cierres diarios, ccxt para criptomonedas y el paquete oficial MetaTrader5 para cotizaciones del bróker. Todo el stack es gratuito y de código abierto.

El ciclo de investigación: de la regla a la validación

Un proyecto avanza en cuatro pasos que conviene mantener bien separados. Primero, escribe las reglas de entrada y salida en lenguaje llano: si no puedes decir «compro cuando la pendiente de la EMA de 50 períodos es positiva y el cierre supera el máximo de los últimos veinte días», no tiene sentido abrir el editor. Segundo, traduce esas reglas a expresiones vectorizadas de pandas: una condición aplicada a toda una columna, sin bucle barra a barra, lo que permite probar diez años de datos H1 en segundos. Tercero, ejecuta el motor sobre el histórico completo con comisión, slippage (deslizamiento), stop loss y take profit, y analiza la curva de capital y el listado de operaciones. Cuarto — donde los principiantes se saltan el paso en silencio — valida fuera de muestra: reserva los últimos dos años, optimiza solo en la ventana anterior y lee el veredicto en datos que no tocaste. La mecánica de ventanas deslizantes está en nuestra guía de análisis walk-forward, y el contexto más amplio en el artículo sobre cómo hacer backtesting de una estrategia.

Lo que Python no hace por sí solo

Un usuario recién llegado lee la documentación de backtrader y asume que la librería lo gestiona todo. No es así. El motor por defecto no sabe nada del spread (la horquilla) de tu bróker, ignora que las cotizaciones se disparan varios pips durante una publicación macro y no modela la comisión de una cuenta ECN de siete dólares por lote en cada lado. Tú introduces todo eso manualmente: commission, slippage_perc, un modelo de horquilla variable por hora. La segunda trampa silenciosa es la calidad de los datos: las series gratuitas de yfinance tienen huecos en fines de semana, y los datos tick de Dukascopy pueden ser irregulares en pares exóticos. El tercer error es la afición a las curvas suaves: un backtesting in-sample con cinco parámetros optimizados casi siempre anuncia un 200 por ciento anual, hasta que eliminas una variable y observas la curva sobre datos que el optimizador nunca vio. Una prueba realista suele mostrar entre un 30 y un 50 por ciento menos que la versión ingenua prometía.

Un ejemplo ilustrativo: proyecto hipotético en EUR/USD

Supón una estrategia de apertura de la sesión de Londres en EUR/USD con barras M15: posición larga cuando el precio supera el máximo de las cinco barras anteriores tras las 9:00 hora de Varsovia, posición corta al perforar el mínimo; stop al 1,5 veces el ATR de veinte períodos, take profit al doble del stop. Descargas datos de 2018 a 2024 con el paquete MetaTrader5, los cargas en pandas y haces el resampling a M15. El backtesting, con una comisión de seis dólares por lote, una horquilla constante de 0,8 pips fuera de ventanas de noticias y un pip de slippage aleatorio en la entrada, devuelve un 51 por ciento de aciertos, factor de beneficio de 1,28, drawdown máximo del 14 por ciento y ratio de Sharpe de 0,9. Dividir el histórico en cuatro años in-sample y dos años fuera de muestra reduce la media out-of-sample aproximadamente un tercio, dejando la decisión de despliegue en un terreno razonable, sin nada espectacular. Todos los números son ilustrativos: muestran la forma de la respuesta, no una promesa.

"Python se ha convertido en un lenguaje de programación y ecosistema de gran potencia para el sector financiero: desde el análisis de datos hasta el trading algorítmico y la gestión del riesgo." — Yves Hilpisch, Python for Finance: Mastering Data-Driven Finance, O'Reilly, 2018

Advertencias honestas que pertenecen a cada informe

Cuando el backtesting concluye, añade un bloque de aclaraciones. Primera: qué horquilla asumiste y si la ampliaste en torno a publicaciones macro — la diferencia entre 0,8 pips constante y 2,5 pips reales durante el NFP suele ser toda la ventaja. Segunda: si los datos están libres de look-ahead bias, es decir, si calculas un indicador a partir del cierre de la barra actual que en tiempo real aún no conocerías. Tercera: cuántos parámetros optimizaste a la vez — cinco es el umbral a partir del cual incluso el walk-forward deja de protegerte. Cuarta: si el resultado sobrevivió fuera de muestra o solo sobre el histórico completo. Sin esas cuatro frases, un informe es marketing, no una auditoría. El taller del trader de ForexMechanics amplía la rutina de investigación.

Si operas desde Latinoamérica, consulta tu regulador local — CNBV (México), CNV (Argentina), CMF (Chile), SBS (Perú) u otro organismo competente en tu país.

Qué hacer mañana

  1. Instala Python 3.11 o superior con pandas, numpy, backtrader, matplotlib y el paquete oficial MetaTrader5 — un solo pip install completa el stack — y descarga dos años de datos H1 del par que realmente operas; guárdalos como CSV para que las iteraciones posteriores trabajen desde una fuente local estable.
  2. Escribe primero las reglas de la estrategia en lenguaje llano — una frase cada una para la entrada, la salida, el stop loss y el take profit — y solo entonces tradúcelas a expresiones vectorizadas de pandas; busca que la prueba completa quepa en treinta líneas sin bucle barra a barra, y resiste la tentación de optimizar parámetros en esta fase.
  3. Ejecuta el backtesting con comisión real, horquilla constante y un pip de slippage aleatorio, y compara el resultado con una versión sin costes; la diferencia te dice qué parte de la ventaja asumida es un artefacto de la ejecución a precio medio — si los costes se llevan más de la mitad del beneficio bruto, la estrategia es demasiado fina para operar en real.
  4. Divide el histórico en cuatro años in-sample y un año fuera de muestra, optimiza como máximo dos parámetros en la ventana in-sample, congela el conjunto ganador y ejecuta el test out-of-sample una sola vez; si el porcentaje de aciertos cae más de un tercio, simplifica la lógica en lugar de buscar una optimización mejor.
  5. Mantén un cuaderno simple — un archivo Markdown en el mismo repositorio — y tras cada backtesting escribe cuatro frases: qué horquilla usaste, si los indicadores evitan el look-ahead bias, cuántos parámetros ajustaste y si la curva de capital fuera de muestra se mantuvo por encima de la mitad del resultado in-sample; sin ese registro, en tres meses habrás olvidado qué informe fue honesto.
Jarosław Wasiński
Sobre el autor

Jarosław Wasiński

Redactor jefe de MyBank.pl · Analista financiero y de mercados

Analista y profesional independiente con más de 20 años en el sector financiero. Fundador y redactor jefe del portal MyBank.pl, en marcha desde 2004. Análisis fundamental de los mercados de divisas y macroeconómicos desde 2007. Escribe desde la perspectiva de los mercados europeos y el marco regulatorio de ESMA.

Fuentes y bibliografía

  1. Backtrader Backtrader documentation — Introduction · oficjalna dokumentacja open-source'owej biblioteki Daniela Rodrigueza: model event-driven, klasy Strategy i Cerebro, integracja danych www.backtrader.com ↗
  2. vectorbt vectorbt usage documentation · oficjalny przewodnik po wektorowym backtestowaniu w numpy/pandas — przykłady i sweep parametrów vectorbt.dev ↗
  3. O'Reilly Media Yves Hilpisch — Python for Finance, 2nd Edition (2018) · kanoniczna pozycja o zastosowaniach Pythona w analityce finansowej, algorytmice i zarządzaniu ryzykiem www.oreilly.com ↗
  4. MQL5 MetaTrader 5 Python Integration — official reference · oficjalne API pakietu MetaTrader5: pobieranie historycznych OHLC i tików, dostęp do konta i składanie zleceń z Pythona www.mql5.com ↗
  5. pandas pandas — Time series / date functionality · referencja czasu w pandas: konwersje, resampling, indeksowanie i przesunięcia używane w każdym backteście pandas.pydata.org ↗

Preguntas frecuentes

¿Necesito Python avanzado para empezar?

El nivel básico de Python es suficiente: bucles, listas, funciones, importar librerías y leer un CSV. El resto es pandas, y lo aprendes sobre la marcha porque todo proyecto de backtesting (prueba retrospectiva) usa las mismas pocas operaciones: cargar datos, hacer resampling, calcular un indicador, definir una condición de entrada y agregar resultados. Una primera estrategia suele caber en treinta líneas de código, así que no tiene sentido esperar a "dominar Python al cien por cien". El ritmo más sano es mantener dos hilos en paralelo: un curso corto de fundamentos (cuatro a seis semanas a una hora diaria) y el proyecto real en el que estás practicando. Si sabes construir una hoja de Excel con fórmulas y entiendes qué es una función, tienes el mínimo necesario — pandas reemplaza prácticamente a la hoja de cálculo, funciona más rápido y te permite validar el trabajo correctamente fuera de muestra.

¿Por qué elegir backtrader en lugar de vectorbt, o al revés?

Las dos librerías siguen filosofías diferentes. Backtrader es event-driven: el motor avanza barra a barra, llama al método next() en tu clase Strategy y reproduce el flujo del trading real — añadir gestión del capital, trailing stop o salidas parciales es directo. El coste es la velocidad: diez años de datos M5 en un solo par pueden tardar varios minutos. Vectorbt toma el camino contrario — expresas toda la estrategia como operaciones vectorizadas sobre columnas de pandas, el motor lo calcula todo en paralelo con numpy y un barrido de cien combinaciones de parámetros termina en decenas de segundos. El coste es el rango expresivo: la lógica de entrada compleja que depende del estado de la cartera es más difícil de codificar. En la práctica, los traders mantienen ambas — vectorbt para la exploración rápida y los barridos de parámetros, backtrader para la validación final del mejor candidato con un modelo realista de comisión y slippage (deslizamiento).

¿Dónde consigo datos históricos fiables?

Tres fuentes, por orden de sentido común. Primera: el paquete oficial MetaTrader5 — recibes el histórico directamente de tu propio bróker, así que el spread (la horquilla), el swap y la comisión en el backtesting coinciden con lo que verás después en una cuenta real. Es la opción más honesta para cualquier estrategia que pienses desplegar. Segunda: Dukascopy publica datos tick y M1 para los pares principales desde 2003 — calidad institucional, pero la horquilla corresponde a la plataforma de Dukascopy, no a la de tu bróker. Tercera: yfinance para cierres diarios y ccxt para mercados de criptomonedas — ambas sirven para prototipado, pero los huecos de fin de semana y los minutos que faltan de vez en cuando las descartan para validar estrategias intradía. Documenta siempre la fuente en la cabecera del script, para que seis meses después aún sepas en qué se basaba el informe — un detalle pequeño que salva el trabajo en cualquier auditoría.

¿Cómo sé que un backtesting es demasiado bueno para ser real?

Cuatro señales son suficientes. Primera: un porcentaje de aciertos superior al 75 por ciento en más de doscientas operaciones — prácticamente inalcanzable fuera del scalping en mercados muy estrechos, así que ese resultado apunta a look-ahead bias o a un error en los datos. Segunda: una curva de capital sin retrocesos significativos — las estrategias reales tienen drawdowns (caídas máximas) de doble dígito, así que una línea ascendente limpia es una advertencia de sobreajuste. Tercera: un factor de beneficio superior a 3,5 — extremadamente raro en forex, donde la horquilla ECN por sí sola consume una parte de dos dígitos de la ventaja. Cuarta: sensibilidad aguda a los parámetros — cuando mover el período de una media móvil de 14 a 12 derrumba el resultado, la estrategia ha aprendido el ruido en lugar de la estructura. Cuando cualquiera de las cuatro señales se enciende al mismo tiempo, el informe es sospechoso sin importar las métricas principales; simplifica la lógica, elimina un parámetro o dos y vuelve a ejecutar el test fuera de muestra.

Profundiza más · la guía completa