De dónde viene la diferencia
«Los backtests son optimistas» es cierto e inútil. La diferencia tiene causas concretas, cada una comprobable en tu propio script, y están repartidas en tres lugares distintos de la documentación.
Supuestos de ejecución a nivel de barra
El tester ejecuta órdenes contra datos de barra. En vivo, ejecutas contra un libro de órdenes.
| Supuesto | Qué oculta [1] |
|---|---|
process_orders_on_close desactivado | las órdenes se ejecutan en la apertura de la barra siguiente, no donde se disparó la señal |
process_orders_on_close activado | se ejecutan al cierre de la barra de señal — mejor alineado, pero solo alcanzable si realmente puedes operar el cierre |
calc_on_order_fills desactivado | el script no se reevalúa al ejecutarse una orden, así que no se modelan secuencias intrabarra que el mercado real produciría |
pyramiding en 1 por defecto | una segunda señal se ignora, tanto en el test como en vivo |
Ninguno está mal. Son decisiones de modelado, y la cuestión es saber cuál tomaste.
La asimetría histórico/tiempo real
Una barra terminada contiene cuatro números. En una barra en formación, el máximo, el mínimo y el cierre siguen moviéndose [2]. El tester funciona sobre barras terminadas; en vivo funcionas sobre una barra que aún no ha terminado.
Ese único hecho produce la mayor parte de la divergencia normal. Una condición
que compara con high compara con un valor definitivo en el test y con uno
provisional en vivo. Una estrategia con calc_on_every_tick se ejecuta en cada
tick en vivo y solo al cierre de barra en el historial [2]: el mismo script, dos
modelos de ejecución.
Los costes, que son el factor individual más grande
La comisión y el slippage son parámetros de la declaración, y un tester sin ninguno de los dos modela un mercado que no te cobra. El slippage se fija en ticks [1], así que equivocarse de unidad escala el error con el tamaño de tick del instrumento.
Esto se trata a fondo en comisión, slippage y capital; la versión corta es que los ajustes de coste suelen explicar más de la diferencia que el momento de ejecución.
Dos que sorprenden
Tipos de gráfico no estándar. TradingView afirma con claridad que producen resultados poco realistas por defecto y que deben usarse gráficos estándar para un backtest realista [1]. Un backtest en Heikin Ashi o Renko no puede reproducirse con ejecuciones reales: las barras mismas son derivadas, no negociadas.
El límite de 9.000 órdenes. Más allá, v6 recorta en silencio las más
antiguas en lugar de dar error [3], y las recortadas devuelven na en
strategy.closedtrades.*. Un backtest largo de alta frecuencia puede por tanto
estar informando sobre un subconjunto de sus propias operaciones.
Reducir la diferencia, por orden de efecto
Ordenado por cuánto mueve cada paso el resultado, de mayor a menor.
1. Pon costes reales. Comisión y slippage de tu propia cuenta, no un número de un artículo. Esto suele explicar más de la diferencia que todo lo demás junto.
2. Prueba en un gráfico estándar. Si el backtest se ejecutó en Heikin Ashi o Renko, el resultado no es comparable con la operativa real [1] y nada más de esta lista lo arreglará.
3. Decide el modelo de ejecución a propósito. Elige
process_orders_on_close con conocimiento y no por defecto, y sé honesto sobre
si puedes operar el cierre de una barra en la temporalidad que pruebas. En un
gráfico diario, a menudo no puedes.
4. Comprueba el lookahead. Si el script usa request.security(), confirma
que no hay fuga de futuro — ver
repintado y lookahead.
Esto es binario: o la ejecución histórica tuvo información que la real no puede
tener, o no.
5. Mira el número de operaciones, no solo el rendimiento. Los costes y los supuestos de ejecución escalan con la frecuencia, así que un resultado de alta frecuencia es mucho más sensible a todo lo anterior. Una estrategia con 40 operaciones no ha sido probada, diga lo que diga su rendimiento.
6. Repite con el doble de tu estimación de coste. Una estrategia que sobrevive a eso es interesante. Una que no, te está diciendo que su resultado es la suposición de coste.
Después opera en papel, y espera que siga habiendo diferencia
La operativa en papel elimina la asimetría histórico/tiempo real [2] porque avanza sobre barras en formación, como en vivo. Lo que no elimina es tu ejecución: una ejecución en papel sigue siendo modelada, no una posición en la cola del libro.
Así que la secuencia que funciona es: backtest para descartar malas ideas barato, papel para detectar los supuestos de ejecución que el backtest ocultó, y después en vivo con tamaño pequeño para descubrir lo que realmente cuestan tus ejecuciones.
El límite honesto de todo esto
Ninguno de estos pasos hace predictivo un backtest. Un tester con costes correctos, barras estándar, un modelo de ejecución deliberado y sin lookahead sigue siendo un modelo, y el mercado no está obligado a parecerse a él.
Lo que el trabajo te compra es distinto y vale más: un test que falla con honestidad. La mayoría de las estrategias que se ven bien con los ajustes por defecto dejan de verse bien cuando los costes son reales — y descubrirlo en el tester no cuesta nada, mientras que descubrirlo en vivo cuesta la cuenta.
Las alertas no son órdenes
El Strategy Tester muestra doscientas operaciones. Tu registro de alertas está vacío. Nada está roto, y esta es la razón documentada:
Las alertas solo se disparan en la barra en tiempo real. [4]
Cada ejecución del backtest es una reproducción del historial. Una alerta es un evento en tiempo real. Nada en la parte histórica del gráfico disparó nunca una alerta, y nunca lo hará: ninguna configuración cambia eso.
La frecuencia que no elegiste
alert(message, freq)
freq vale alert.freq_once_per_bar por defecto [4]. Hay tres valores:
| Constante [4] | Se dispara |
|---|---|
alert.freq_once_per_bar | la primera vez que la condición es cierta en la barra — el valor por defecto |
alert.freq_once_per_bar_close | solo al cierre confirmado de la barra |
alert.freq_all | cada vez que la condición es cierta |
Si tu estrategia decide al cierre de la barra, el valor por defecto es el equivocado. Te avisará de una condición intrabarra que ya se ha revertido cuando la barra cierra: el problema del repintado con otro disfraz, y la razón por la que un flujo de alertas en vivo puede contradecir al backtest que lo generó.
Alertas de ejecución de órdenes y su texto
Una alerta de script creada desde una estrategia puede configurarse para que
los eventos de ejecución de órdenes también la disparen [4]. El texto por orden
viene del parámetro alert_message, que aceptan strategy.entry(),
strategy.exit(), strategy.close() y strategy.order() [4]; lo recuperas en
el cuerpo de la alerta con el marcador {{strategy.order.alert_message}} [4].
Otros marcadores disponibles en los mensajes de alerta incluyen {{ticker}},
{{exchange}}, {{interval}}, {{close}}, {{time}} y {{timenow}} [4].
La parte que TradingView no promete
Una alerta es una notificación. No coloca una orden en tu bróker. Pasar de una alerta disparada a una posición abierta requiere una integración con el bróker, y el retardo entre ambas es tuyo: no está en el tester, que asume que la ejecución ocurrió al precio que modeló. Ese retardo es una parte más de la diferencia de la que trata esta página, y ningún ajuste del tester la elimina.
Los límites que deciden tus resultados
Parte de lo que informa tu backtest lo decide tu cuenta, no tu estrategia. Conviene saberlo antes de gastar un fin de semana depurando uno de estos límites.
Tu plan cambia tu backtest
Barras históricas disponibles, por plan [3]:
| Plan [3] | Barras históricas |
|---|---|
| Ultimate | 40.000 |
| Expert | 25.000 |
| Premium | 20.000 |
| Essential y Plus | 10.000 |
| Otros planes | 5.000 |
Lee esa tabla otra vez, porque la consecuencia es mayor de lo que parece: dos personas que ejecutan un script idéntico en un símbolo y temporalidad idénticos obtienen backtests distintos. Quien tiene más historial prueba más regímenes de mercado, y quien tiene menos puede no llegar al drawdown que le habría hecho cambiar de opinión.
Así que una cifra de backtest publicada no es reproducible si no se indica el plan junto a él. Si publicas una cifra, indica tu plan; si lees una que no lo hace, no puedes comprobarla.
El tope de órdenes, otra vez
El tope de 9.000 órdenes de arriba sube a 1.000.000 con Deep Backtesting [3]. Un script que opera con frecuencia sobre un rango largo alcanza las 9.000 y la curva se aplana mientras las estadísticas siguen pareciendo verosímiles, así que compara el número de operaciones con el tope antes de concluir que la estrategia dejó de funcionar.
Tiempo de ejecución, que hace fallar un script que antes pasaba
El tiempo asignado para ejecutarse sobre todas las barras de un conjunto de datos es de 20 segundos para cuentas básicas y 40 para las demás [3].
Este confunde porque tu lógica no tiene que cambiar para alcanzarlo. Añade
barras, añade una llamada request.*, cambia a un símbolo con más historial, y
un script que funcionaba ayer agota el tiempo hoy.
Qué comprobar de verdad, y con qué frecuencia
Primero, lo que no tienes que hacer: mantener una máquina encendida. Una estrategia Pine se ejecuta en el gráfico de TradingView, no en tu ordenador, así que no hay terminal que reiniciar ni VPS que alquilar. Esta es la diferencia estructural con un Expert Advisor de MT5, y casi todo el consejo de mantenimiento que encontrarás para Pine es un artículo de MT5 con las palabras cambiadas — ver desplegar y mantener un EA para lo que aquello sí requiere.
Lo que queda es comprobar que sigue siendo cierto lo que tu backtest asumió.
Tras cada re-export — la declaración
Es la única comprobación obligatoria, porque la declaración strategy() es
donde se deciden tus resultados y una exportación nueva la reescribe.
| Confirma | Porque |
|---|---|
commission_type y commission_value están fijados | una exportación por defecto puede no costar nada |
slippage está en ticks de este instrumento | un tick no mide lo mismo en dos símbolos |
pyramiding es el número que querías | vale 1 por defecto [1]; un valor mayor acumula posiciones |
| cada control de entrada cambia el comportamiento de verdad | mueve un umbral y confirma que la lista de operaciones cambia |
Esa última fila no es paranoia. Una entrada declarada pero nunca referenciada en la lógica genera un control que funciona y no hace nada, y no hay forma de saberlo mirándolo — ver los parámetros de coste en detalle.
Cada semana — dos comprobaciones
Elige tres operaciones de la List of Trades y búscalas en el gráfico. ¿Corresponde el precio de ejecución a un precio al que esa barra realmente operó? Esta única comprobación detecta fuga de futuro, un tipo de gráfico no estándar y un tamaño de tick mal leído, y cuesta menos de un minuto.
Confirma que tu filtro de sesión sigue coincidiendo con el horario del instrumento. El horario de verano lo mueve dos veces al año, y una cadena de sesión se interpreta en la zona horaria del mercado, no del gráfico — las reglas de los filtros de sesión explican por qué eso hace daño.
Cada mes — ¿sigue operando?
Una estrategia que ha dejado de abrir posiciones está o en un régimen de mercado para el que no fue construida, o tiene una condición que ya no llega a ser cierta. En la curva de capital ambas cosas son idénticas: una línea plana.
Distínguelas dibujando la condición en sí, no el resultado. Si la condición se
cumple y no siguen órdenes, mira pyramiding, el tope de órdenes, o un filtro
que ahora es permanentemente falso. Si la condición no se cumple nunca, el
mercado cambió — y eso es una decisión que tomar, no un fallo que arreglar.
Lo que no hay que comprobar
El código, salvo que lo cambiaras tú o lo cambiara la plataforma. Los valores por defecto de cada versión son la excepción que merece un recordatorio en el calendario: los cambios de v5 a v6 alteraron comportamientos sin dar error, y esa clase de cambio es la única que puede romper un script que nunca tocaste.

