Convierte un indicador de Pine Script en estrategia y automatízala.
Tu indicador pinta flechas en el gráfico, pero las flechas ni se pueden backtestear ni operan. Esta guía convierte un indicador de Pine Script v6 en estrategia línea a línea, hace honesto el backtest, quita las trampas del repintado y envía cada ejecución de orden a MetaTrader 5 como un JSON que el puente entiende.
La respuesta corta
Convertir un indicador en estrategia son cinco cambios, no reescribirlo. Todo lo de abajo está contrastado con la documentación oficial de Pine Script v6 de TradingView (verificado el 4 de octubre de 2026).
- Cambia la declaración:
indicator()pasa a serstrategy(), con capital, tamaño de posición, comisión y slippage. - Convierte señales en órdenes: cada condición de
plotshape()oalertcondition()dispara unstrategy.entry(),strategy.close()ostrategy.exit(). - Haz honesto el backtest: costes reales, tamaño razonable y nada de datos del futuro.
- Quita el repintado: sin fugas de
lookaheady sincalc_on_every_ticksalvo que lo necesites de verdad. - Alerta en las ejecuciones de órdenes: pega un JSON a cada orden con
alert_messagey pon{{strategy.order.alert_message}}en la alerta.
Si aún no has decidido si pasar tu lógica a MQL5, lee antes Pine Script a EA: las 3 formas reales. Esta página da por hecho que la lógica sigue en TradingView y solo la conviertes de indicador a estrategia.
Paso 1: indicator() pasa a ser strategy()
En la declaración la estrategia recibe todo lo que un indicador nunca necesitó: dinero, tamaño y costes. Estos son los parámetros de strategy() que importan al convertir:
initial_capitaldefault_qty_type / default_qty_valuestrategy.fixed, strategy.percent_of_equity o strategy.cash.pyramidingcommission_type / commission_valuestrategy.commission.percent, cash_per_contract o cash_per_order.slippagemargin_long / margin_shortcalc_on_every_tickprocess_orders_on_closeDos detalles de v6 que rompen código viejo: el parámetro when se eliminó de strategy.entry(), strategy.close() y el resto de funciones de órdenes (usa un bloque if), y alertcondition() compila dentro de una estrategia, pero TradingView no te deja crear alertas a partir de ella.
Paso 2: las señales pasan a ser órdenes
Un indicador dice "ha pasado algo". Una estrategia dice "haz esto con la posición". La equivalencia es mecánica:
Este es un indicador mínimo: dos EMA, flechas en los cruces y dos condiciones de alerta.
//@version=6
indicator("EMA cross - indicator", overlay = true)
fastLen = input.int(9, "Fast EMA")
slowLen = input.int(21, "Slow EMA")
fast = ta.ema(close, fastLen)
slow = ta.ema(close, slowLen)
longSignal = ta.crossover(fast, slow)
shortSignal = ta.crossunder(fast, slow)
plot(fast, "Fast", color.lime)
plot(slow, "Slow", color.orange)
plotshape(longSignal, "Long", shape.triangleup, location.belowbar, color.lime)
plotshape(shortSignal, "Short", shape.triangledown, location.abovebar, color.red)
alertcondition(longSignal, "Long", "EMA cross up")
alertcondition(shortSignal, "Short", "EMA cross down")Y la misma lógica como estrategia. Las líneas de la señal no cambian; solo cambian la declaración y el último bloque.
//@version=6
strategy("EMA cross - strategy", overlay = true,
initial_capital = 10000,
default_qty_type = strategy.fixed, default_qty_value = 1,
pyramiding = 1,
commission_type = strategy.commission.percent, commission_value = 0.01,
slippage = 2)
fastLen = input.int(9, "Fast EMA")
slowLen = input.int(21, "Slow EMA")
fast = ta.ema(close, fastLen)
slow = ta.ema(close, slowLen)
longSignal = ta.crossover(fast, slow)
shortSignal = ta.crossunder(fast, slow)
plot(fast, "Fast", color.lime)
plot(slow, "Slow", color.orange)
// JSON para el puente. SL/TP en pips (unidad por defecto del dashboard)
sym = syminfo.ticker
buyMsg = '{"action":"buy","symbol":"' + sym + '","sl":30,"tp":60}'
sellMsg = '{"action":"sell","symbol":"' + sym + '","sl":30,"tp":60}'
if longSignal
strategy.entry("Long", strategy.long, alert_message = buyMsg)
if shortSignal
strategy.entry("Short", strategy.short, alert_message = sellMsg)
// Los mismos 30/60 pips en el backtest (FX de 5 decimales: 1 pip = 10 ticks)
strategy.exit("XL", "Long", loss = 300, profit = 600,
alert_message = '{"action":"close","symbol":"' + sym + '","side":"buy"}')
strategy.exit("XS", "Short", loss = 300, profit = 600,
alert_message = '{"action":"close","symbol":"' + sym + '","side":"sell"}')Por qué está hecha así. El stop y el objetivo viajan con la entrada ("sl":30,"tp":60, en pips, la unidad por defecto de SignalForge), así que la posición queda protegida en el bróker aunque una alerta posterior no llegue nunca. Las llamadas a strategy.exit() replican esas distancias en el backtest: en un par de forex con 5 decimales un pip son 10 ticks, así que 300 y 600 ticks son 30 y 60 pips. En otros símbolos, recalcúlalo. Los mensajes de cierre llevan "side" para que la salida del largo solo cierre compras. Y no hay campo lot: el EA calcula el tamaño con el tipo de tamaño de posición de tu dashboard.
El cruce de EMA es un ejemplo para enseñar la mecánica. No es una ventaja probada y nada en esta página dice que sea rentable.
Paso 3: haz honesto el backtest
- Las órdenes se llenan en la vela siguiente. Con la configuración por defecto, el emulador del bróker llena cada orden nueva en la apertura de la vela siguiente. Un webhook real sale segundos después del cierre de la vela de la señal, así que es lo que más se parece. Activar
process_orders_on_closete da un precio que tu alerta real nunca conseguiría. - Los costes no son opcionales. Pon en
commission_type,commission_valueyslippagelos números de tu bróker. Una estrategia que solo funciona a coste cero no funciona. - El tamaño va en unidades de TradingView, no en lotes de MT5. Según el símbolo,
default_qty_valuecuenta contratos, acciones o unidades de la divisa base. Elige un valor que reproduzca tu exposición real y recuerda que MT5 aplicará sus propias reglas de lote. - El spread lo modelas tú. Los datos de TradingView no son el feed de tu bróker. Comprueba los resultados en una demo de MT5 antes de fiarte de la curva.
Paso 4: quita el repintado antes de que llegue a tu cuenta
La documentación de TradingView define el repintado como un comportamiento del script distinto entre velas históricas y en tiempo real, y calcula que más del 95% de los indicadores lo tienen de alguna forma. Pasar a estrategia no lo arregla: lo deja al descubierto. Revisa tres cosas:
request.security()con lookahead. Usarlookahead = barmerge.lookahead_onsin desplazar la serie mete datos del futuro en las velas históricas. El patrón oficial sin repintado lo combina con[1]:
// Temporalidad superior sin fuga de futuro (patron de la doc de Pine)
htfClose = request.security(syminfo.tickerid, "D", close[1], lookahead = barmerge.lookahead_on)calc_on_every_tick = true. La estrategia se ejecuta entonces en cada actualización en tiempo real, mientras que el histórico se calculó al cierre de cada vela, así que lo más probable es que las órdenes reales no coincidan con el backtest. Déjalo apagado salvo que tu lógica necesite de verdad los ticks.- Una vez por cierre de vela. Por defecto las estrategias se ejecutan al cierre de las velas en tiempo real y, salvo que actives
calc_on_every_tick, cadaalert()de una estrategia salta una vez por cierre de vela pases la frecuencia que pases. Si automatizas el indicador en vez de la estrategia, añadeand barstate.isconfirmeda la condición o usaalert.freq_once_per_bar_close.
Más sobre frecuencias de alerta y la función alert() en alert() de Pine Script para webhooks.
Paso 5: alertas de ejecución que el puente entiende
Crea una sola alerta sobre la estrategia. En la condición elige la estrategia y sus eventos de ejecución de órdenes (order fills); en el mensaje pon solo el marcador de abajo; en la pestaña Notificaciones marca URL del webhook y pega tu URL de SignalForge (el token va en la URL, nunca en el JSON). Los webhooks necesitan un plan de pago de TradingView (Essential o superior).
{{strategy.order.alert_message}}Cada ejecución envía ahora el JSON pegado a esa orden. TradingView sustituye el marcador por una cadena vacía en las órdenes sin alert_message, y un cuerpo vacío se rechaza con HTTP 400, así que dale a cada llamada de orden su propio mensaje.
También puedes montar el mensaje en el diálogo con los marcadores genéricos, y es tentador:
{"action":"{{strategy.order.action}}","symbol":"{{ticker}}","lot":{{strategy.order.contracts}}}{{strategy.order.action}}solo devuelve "buy" o "sell". Una ejecución que cierra un largo es una venta. Enviada como"action":"sell", el EA cierra la compra y luego abre una venta, mientras tu estrategia está plana. Los mensajes explícitos"action":"close"lo evitan.{{strategy.order.contracts}}no es un lote. Es la cantidad de la estrategia en unidades de TradingView. Un valor fuera de 0,01-500 se rechaza con HTTP 422 y, en modo de lote fijo (el predeterminado del dashboard, 0,01), ellotde la alerta se ignora igualmente. Usa el modo de lote de la señal solo si mandas un lote calculado para MT5.{{ticker}}es el nombre de TradingView. El EA resuelve solo los sufijos habituales de los brókers, pero si tu bróker usa otro nombre (GOLD en vez de XAUUSD, por ejemplo), manda el nombre del bróker. Detalle en símbolo, lote o cuenta equivocados en MT5.- Nunca generes
"account"con un marcador. Escribe el login como literal entre comillas; el formato numérico puede meter separadores de miles y romper el JSON.
Otros formatos (órdenes pendientes, cierres parciales con percent, comentarios para separar estrategias) están en los ejemplos de JSON para el webhook de TradingView y en la documentación.
Antes de operar en real
- Valida el JSON. Pega el mensaje exacto que produce cada orden en el tester de webhooks gratuito. Una comilla que falta en una cadena concatenada es el fallo más habitual.
- Vuelve a crear la alerta tras cada cambio. TradingView ejecuta una copia guardada del script, las entradas, el símbolo y la temporalidad; los cambios no llegan a una alerta ya creada.
- Pruébalo primero en una cuenta demo. En el dashboard cada señal aparece como EXECUTED, FILTERED, FAILED, NOT_DELIVERED o PENDING con su motivo, y la pestaña Expertos de MT5 muestra
[PROC]cuando llega la señal y[SEND]cuando sale la orden. - Revisa tus filtros. El pyramiding por defecto es una operación por dirección y símbolo, y los filtros horario, de noticias y de tendencia o el Prop Firm Shield pueden bloquear a propósito una entrada válida.
- Desde el gráfico cuenta segundos, no milisegundos. En SignalForge medimos unos 0,5 s de mediana del webhook a la orden confirmada (del 19 al 23 de septiembre de 2026, benchmarks), pero TradingView tarda unos segundos en enviar el webhook tras el cierre de la vela.
Preguntas frecuentes
¿Puedo convertir cualquier indicador de TradingView en estrategia?
Solo si puedes editar su código. Los scripts de código abierto se pueden copiar y modificar; los protegidos y los de solo invitación ocultan el código, así que no puedes añadirles llamadas a strategy(). En ese caso quédate con el indicador y automatiza sus propias alertas.
¿Necesito una estrategia para automatizar un indicador de Pine Script?
No. Un indicador también puede enviar webhooks, con alertcondition() o alert(). La estrategia aporta dos cosas: un backtest con comisión y slippage, y una única alerta de ejecución de órdenes que cubre todas las entradas y salidas del script.
¿Por qué mis alertas en vivo no coinciden con el backtest?
Causas habituales: el backtest llena en la apertura de la vela siguiente mientras la orden real se ejecuta segundos después del cierre, lógica que repinta (request.security con lookahead, calc_on_every_tick), comisión y slippage sin configurar y el spread real de tu bróker. TradingView además tarda unos segundos en enviar el webhook.
¿Debo mandar {{strategy.order.contracts}} como lote de MT5?
Normalmente no. TradingView cuenta la cantidad de la estrategia en sus propias unidades (contratos, acciones o unidades de divisa según el símbolo), no en lotes de MT5. Manda un lote que hayas elegido tú o no mandes lote y deja que el dashboard calcule el tamaño. En modo de lote fijo el lote de la alerta se ignora de todos modos.
¿Qué pasa en MT5 cuando la estrategia gira de largo a corto?
El giro llega como una sola ejecución de venta. Con la cobertura desactivada, que es lo predeterminado en SignalForge, una señal contraria cierra primero la compra abierta y después se ejecuta la venta, así que MT5 sigue a la estrategia.
¿Tengo que volver a crear la alerta después de editar el script?
Sí. TradingView guarda una copia del script, las entradas, el símbolo y la temporalidad al crear la alerta, así que los cambios posteriores no llegan a una alerta activa. Bórrala y crea una nueva, con la URL del webhook otra vez.
Sigue leyendo
Más soluciones
- Webhook recibido pero sin operación en MT5
- Símbolo, lote o cuenta equivocados en MT5
- Órdenes duplicadas en el trading automático
- Qué pasa cuando se reinicia el puente
- Checklist de cumplimiento prop firm al automatizar
- Error 415 del webhook de TradingView · Error 4756 de MT5 · Configurar el webhook de TradingView
Tu estrategia en TradingView. Sus órdenes en MT5.
Envía cada ejecución de tu estrategia de Pine a MetaTrader 5, con lote, filtros y Prop Firm Shield configurados por cuenta. Prueba gratis 14 días, sin tarjeta.
SignalForge AI es una herramienta de ejecución de órdenes. No ofrecemos asesoramiento de inversión. El código de esta página es un ejemplo educativo, no una estrategia rentable ni backtesteada. Operar conlleva riesgo de pérdida.