PINE SCRIPT V6 · ACTUALIZADO OCTUBRE 2026

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.

BBenjamin SF · Fundador Publicado 4 oct 2026 Lectura 9 min

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 ser strategy(), con capital, tamaño de posición, comisión y slippage.
  • Convierte señales en órdenes: cada condición de plotshape() o alertcondition() dispara un strategy.entry(), strategy.close() o strategy.exit().
  • Haz honesto el backtest: costes reales, tamaño razonable y nada de datos del futuro.
  • Quita el repintado: sin fugas de lookahead y sin calc_on_every_tick salvo que lo necesites de verdad.
  • Alerta en las ejecuciones de órdenes: pega un JSON a cada orden con alert_message y 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:

Parámetro
Qué controla
Para empezar
initial_capital
Saldo inicial del backtest.
El tamaño real de tu cuenta.
default_qty_type / default_qty_value
Tamaño de la orden: strategy.fixed, strategy.percent_of_equity o strategy.cash.
La exposición que vas a operar de verdad, en unidades de TradingView.
pyramiding
Máximo de entradas en la misma dirección. Por defecto 1.
Déjalo en 1 salvo que tu lógica escale posiciones.
commission_type / commission_value
strategy.commission.percent, cash_per_contract o cash_per_order.
La comisión real de tu bróker. A coste cero cualquier backtest sale bonito.
slippage
Ticks extra en las ejecuciones a mercado y de stop.
Unos pocos ticks; más en símbolos que se mueven con noticias.
margin_long / margin_short
Control de margen. En v6 el valor por defecto es 100 (en v5 era 0, sin control).
El de v6, salvo que conozcas tu apalancamiento.
calc_on_every_tick
Recalcular en cada tick en tiempo real en vez de al cierre de la vela.
false (por defecto). Mira la sección de repintado.
process_orders_on_close
Ejecutar al cierre de la vela de la señal en vez de en la apertura siguiente.
false, para parecerse a lo que una alerta real puede hacer.

Dos 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:

Indicador → estrategia, pieza a pieza
plotshape(longSignal)
→
strategy.entry("Long", strategy.long). Si hay un corto abierto, la entrada lo gira automáticamente.
plotshape(shortSignal)
→
strategy.entry("Short", strategy.short). El mismo giro en la otra dirección.
condición de salida
→
strategy.close("Long") cierra a mercado la posición abierta con ese id de entrada.
SL / TP fijos
→
strategy.exit("XL", "Long", loss = ..., profit = ...), distancias en ticks.
escalar, sin giro automático
→
strategy.order() ignora el pyramiding y nunca gira por sí sola. Úsala solo si gestionas tú la posición.
alertcondition(...)
→
alert_message en cada llamada de orden, leído por una sola alerta de ejecuciones.

Este es un indicador mínimo: dos EMA, flechas en los cruces y dos condiciones de alerta.

Antes: el indicadorPINE v6
//@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.

Después: la estrategia, con alertas listas para el puentePINE v6
//@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_close te da un precio que tu alerta real nunca conseguiría.
  • Los costes no son opcionales. Pon en commission_type, commission_value y slippage los 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_value cuenta 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. Usar lookahead = barmerge.lookahead_on sin desplazar la serie mete datos del futuro en las velas históricas. El patrón oficial sin repintado lo combina con [1]:
Valor de temporalidad superior, sin fuga de futuroPINE v6
// 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, cada alert() 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ñade and barstate.isconfirmed a la condición o usa alert.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).

Diálogo de alerta, cuadro de mensajeMARCADOR
{{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:

Tentador, pero arriesgadoJSON
{"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), el lot de 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.

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.

¿Estrategia lista? Envía sus ejecuciones a MT5 · desde 4,99 $/mesVer precios →