From Pine Script Indicator to Live Automated Strategy: A Practical Guide
Turn a Pine Script indicator into a strategy that emits an executable alert, then route it to MetaTrader 5. Syntax, the alert call, and what breaks.

Your indicator draws the signals correctly. Arrows appear, colours change, the logic holds up, and then nothing happens. Every entry still needs you at the chart, clicking the order ticket.
This guide covers the Pine Script side of closing that gap: converting an indicator() into a strategy(), and emitting an alert that a bridge can turn into an order on MetaTrader 5. The code below demonstrates syntax. The trading logic in it is a placeholder for your own and is not a system to trade.
Everything uses Pine Script v6, current since TradingView shipped it in December 2024. v5 scripts still run, and the Pine Editor converts them through the "Manage script" menu.
Indicator or strategy: which one you automate
Pine Script has two script types:
indicator()draws things. Plots, arrows, backgrounds. It can signal, but it does not track a position or model an order.strategy()simulates trading. It hasstrategy.entry,strategy.exit, position sizing, and the Strategy Tester report.
Both can fire alerts, so both can drive a bridge. The reason to convert is the report: a strategy() lets you see whether the logic behaves the way you think it does before anything is connected.
Step 1: Isolate the entry conditions
Automation starts with the booleans, not the drawing. Whatever your indicator plots, find the expressions underneath it:
1//@version=62indicator("Syntax example", overlay = true)34// Placeholder logic. Substitute the conditions your own indicator computes.5fast = ta.sma(close, 10)6slow = ta.sma(close, 30)7longCondition = ta.crossover(fast, slow)8shortCondition = ta.crossunder(fast, slow)910plotshape(longCondition, style = shape.triangleup, location = location.belowbar)11plotshape(shortCondition, style = shape.triangledown, location = location.abovebar)12
longCondition and shortCondition are the only two things the automated version needs. Everything else in an indicator is presentation.
Step 2: Rebuild it as a strategy
Swap indicator() for strategy() and turn the conditions into orders:
1//@version=62strategy("Syntax example", overlay = true)34fast = ta.sma(close, 10)5slow = ta.sma(close, 30)6longCondition = ta.crossover(fast, slow)7shortCondition = ta.crossunder(fast, slow)89if longCondition10 strategy.entry("Long", strategy.long)1112if shortCondition13 strategy.entry("Short", strategy.short)14
If you add strategy.exit, note that its loss and profit arguments are counted in ticks, not pips. On a five-digit forex symbol, 300 ticks is 30 pips. Reading one as the other is a common reason a tester report looks nothing like the intended system.
The distinction that matters once you go live: anything you define inside the strategy applies to the simulation. TradingView is not connected to your broker and cannot place, modify or close anything. When the script runs live, what executes is the message it sends and whatever the receiving software does with it.
Step 3: Emit an alert the bridge can execute
Pine Script's alert() fires at runtime and builds its message in code, which is what makes per-signal payloads possible:
1//@version=62strategy("Syntax example", overlay = true)34routingId = input.string("PLACEHOLDER_ID", "Routing ID")5brokerSymbol = input.string("PLACEHOLDER_SYMBOL", "Broker symbol")67fast = ta.sma(close, 10)8slow = ta.sma(close, 30)9longCondition = ta.crossover(fast, slow)10shortCondition = ta.crossunder(fast, slow)1112payload(action) =>13 routingId + "," + action + "," + brokerSymbol + ",sl=100,tp=200"1415if longCondition16 strategy.entry("Long", strategy.long)17 alert(payload("buy"), alert.freq_once_per_bar_close)1819if shortCondition20 strategy.entry("Short", strategy.short)21 alert(payload("sell"), alert.freq_once_per_bar_close)22
The message format is whatever your bridge parses. NexumTrader reads single-line, comma-separated payloads rather than JSON, in the shape id,action,SYMBOL,sl=NN,tp=NN, with variants for closing and modifying positions. The webhook payload reference has the complete grammar, and the quick start covers connecting the terminal.
Two things about that string are worth stating explicitly, because both are easy to get wrong and neither is obvious.
Keep identifiers out of published scripts
The payload carries an identifier that tells the bridge which account set the signal belongs to. Reading it as an input.string rather than hard-coding it means one script serves several charts. It also means that if you publish the script on TradingView, you publish with a placeholder rather than your own ID.
The symbol has to be your broker's notation
syminfo.ticker returns TradingView's name for the instrument, and brokers frequently disagree: XAUUSD against GOLD, or a suffix like EURUSD.pro. The symbol in the payload is the string the terminal looks up, so it has to match what the terminal actually calls the instrument.
Plenty of older automation guides recommend syminfo.ticker for flexibility. It is also a common reason alerts fire into nothing. Set it explicitly and check it against Market Watch.
alert() against alertcondition()
alert()fires at runtime, builds the message in code, and works inside strategies.alertcondition()declares a named condition you wire up by hand in the alert dialog, with a static message. Workable for a simple notification, awkward for per-trade payloads.
Step 4: Connect it and check it on demo
In TradingView, open the alert dialog on the strategy, set the condition to Any alert() function call, leave the message box empty because the script supplies it, and paste the bridge's webhook URL under Notifications. Trigger frequency Once Per Bar Close unless you have a reason to fire intrabar.
On the MetaTrader side the terminal has to be running with algo trading enabled and the bridge's Expert Advisor attached to a chart of the symbol you are routing. NexumTrader's quick start walks the terminal setup, and How a Signal Flows explains what happens between the alert and the order.
Then run it on a demo account and compare, alert by alert:
- Did the symbol resolve, or did the signal arrive for an instrument with no chart attached?
- Did the direction, stop and target arrive as the script built them?
- Did it open on bar close, without duplicates?
- Do the recorded signals match the orders? A signal that did not execute is logged with a reason, which is faster to read than guessing.
Common pitfalls
- Repainting. An indicator that recalculates intrabar will not reproduce live what the tester showed. Confirm on bar close, or gate on
barstate.isconfirmed. - Lookahead bias. Requesting higher-timeframe data with lookahead enabled inflates the tester report and breaks live behaviour.
- Ticks against pips.
strategy.exitcounts ticks. The payload counts whatever unit the receiving software is configured for. Two units in one system. - JSON. A payload built as JSON will not parse against a comma-separated grammar. Match the format your bridge documents.
- The terminal closed. Automation needs the platform running, which in practice means an always-on machine.
- Symbol mismatch. Still the single most common cause of "the alert fired and nothing happened".
FAQ
Can you automate a Pine Script indicator directly?
Not by itself. An indicator() only draws. Adding alert() calls to it works, or convert it to a strategy() so you also get the tester report.
Does Pine Script run on MetaTrader 5?
No. Pine Script runs only on TradingView. Automation means TradingView sends an alert to a bridge, which executes it through an MT5 Expert Advisor.
What is the difference between alert() and alertcondition()?alert() fires at runtime with a message built in code and works inside strategies. alertcondition() defines a fixed condition you configure by hand in the alert dialog.
Do I have to convert my indicator into a strategy?
No. You can add alert() calls to an indicator. Converting gives you the Strategy Tester report, which is the reason most people do it.
Why don't live orders match the tester?
Usually repainting, lookahead bias, or a stop and target defined differently in the script than in the alert payload. Anything inside strategy() applies to the simulation only.
Which Pine Script version should I write in?
v6, current since December 2024. The Pine Editor converts v5 scripts through the "Manage script" menu.
This article describes how Pine Script alerts and order routing work between TradingView and MetaTrader 5. It is not financial, investment or trading advice, and nothing in it is a recommendation to trade, to use any strategy, or to size a position in any particular way. The code is a syntax illustration and the logic in it is a placeholder, not a system to trade. Backtested results do not indicate future performance. NexumTrader is order-routing software: it does not provide trading signals, portfolio management or investment recommendations. Trading carries risk of loss.
Route your alerts to every MT5 account.
Per-account risk, trading windows and session rules, from a single TradingView alert.
Keep reading

TradingView Alert Not Working? Find the Point Where the Signal Died
Your alert fired and no trade appeared. Work down the five points where a TradingView signal dies before it reaches MT5, symptom first.

Do You Need a VPS for Automated MT5 Trading? What Always-On Actually Requires
Automated MT5 trading needs a terminal that never closes. Why that means Windows, when MetaTrader's own VPS is enough, and what to check before buying.

How to Automate a Prop Firm Challenge with TradingView Alerts (Without Breaking the Rules)
Automate your prop firm challenge with TradingView alerts on MT5, the compliant way. Rules, risk controls and setup for FTMO, FundedNext and more.