Nyria Docs
Alert sourcesTradingView

Convert a TradingView Indicator to a Strategy

Turn an indicator() Pine Script into a strategy() so a single "Order fills only" alert covers every entry and exit — instead of wiring a separate alert per signal, per ticker.

If your TradingView script is an indicator(), you have to create a separate alert for every signal — long entry, long exit, short entry, short exit — and repeat that for every ticker. Convert it to a strategy() and a single Order fills only alert covers all of them, one per ticker. The signal logic doesn't change; only the script's outputs do.

Why Nyria nudges you here. With an indicator, 4 sides × 5 tickers = 20 alerts to create and keep in sync. The same script as a strategy is 5 alerts — one per ticker — each firing on every order the strategy generates.

Indicator vs. strategy alerts

indicator()strategy()
How it signalsplotshape, alertcondition, alert()strategy.entry / strategy.exit / strategy.close orders
Alerts you createOne per condition, per tickerOne "Order fills only" alert, per ticker
Message placeholdersYou hand-write the action/direction in each alert{{strategy.order.action}}, {{strategy.market_position}}, … resolve automatically
BacktestableNoYes — runs in the Strategy Tester

What actually changes

Converting is usually a three-line change. Your indicator math — the EMAs, RSI, crossovers, whatever produces your signals — stays exactly the same. You only swap the declaration and replace each signal output with an order call.

Swap indicator(...) for strategy(...). Add process_orders_on_close=true so orders fill on the confirmed bar close (this matches the Once Per Bar Close alert timing Nyria recommends) and calc_on_every_tick=false to avoid intra-bar repainting.

Replace each signal output with an order call. Wherever your indicator drew an arrow or declared an alertcondition, call strategy.entry() to open and strategy.close() (or the opposite-side strategy.entry()) to exit.

Delete the old alertcondition() / alert() calls. You no longer need them — the single Order-fills alert replaces every one of them.

Before — an indicator

//@version=5
indicator("EMA Cross", overlay=true)

fast = ta.ema(close, 9)
slow = ta.ema(close, 21)

long  = ta.crossover(fast, slow)
short = ta.crossunder(fast, slow)

plotshape(long,  title="Long",  style=shape.triangleup,   location=location.belowbar, color=color.green)
plotshape(short, title="Short", style=shape.triangledown, location=location.abovebar, color=color.red)

// Each of these becomes its OWN TradingView alert — per ticker:
alertcondition(long,  title="Long entry",  message="open long")
alertcondition(short, title="Short entry", message="open short")

After — the same logic as a strategy

//@version=5
strategy("EMA Cross", overlay=true, process_orders_on_close=true, calc_on_every_tick=false)

fast = ta.ema(close, 9)
slow = ta.ema(close, 21)

long  = ta.crossover(fast, slow)
short = ta.crossunder(fast, slow)

if long
    strategy.entry("Long", strategy.long)
if short
    strategy.entry("Short", strategy.short)   // entering short auto-closes the long

The signal logic is untouched — only the outputs changed, from drawings/alertconditions to orders. Now the strategy emits a real order on every signal, and one alert can listen to all of them.

Choosing your exit pattern

How you close depends on which directions you trade:

  • Long-only — open with strategy.entry("Long", strategy.long) and exit with strategy.close("Long"). Nyria sends a buy, then a sell-to-close.
  • Long and short (flip) — open each side with strategy.entry. Entering one side automatically closes the other, so a single signal both exits and reverses — exactly what Nyria's exit-opposite behavior expects.
  • Stops / targets — add strategy.exit("x", from_entry="Long", stop=..., limit=...). Nyria still receives one order-fill alert when the stop or target fills.

Position size lives in Nyria, not Pine. Use any qty in your script — the default of 1 is fine. Nyria reads the action and direction from the alert, then sizes the real order from your bot's allocation settings. The Pine quantity only needs to be ≥ 1 so the strategy actually generates fills.

Create the one alert

You now need a single alert per ticker. In the Nyria alert wizard, pick A Strategy and copy the default message — or paste this directly into TradingView's Message box:

{
  "action": "{{strategy.order.action}}",
  "instrument": "{{ticker}}",
  "marketPosition": "{{strategy.market_position}}",
  "prevMarketPosition": "{{strategy.prev_market_position}}",
  "contracts": "{{strategy.order.contracts}}",
  "price": {{close}}
}

Each placeholder resolves at fire time:

FieldTradingView placeholderWhat Nyria does with it
action{{strategy.order.action}}buy or sell — mapped to entry/exit via your strategy config.
marketPosition{{strategy.market_position}}long, short, or flat after this fill — lets Nyria detect flips.
prevMarketPosition{{strategy.prev_market_position}}Position before the fill — disambiguates a close from a reverse.
contracts{{strategy.order.contracts}}The strategy's order size (informational — Nyria sizes from your allocation).
price{{close}}Confirmed bar close, used for limit pricing and sizing math.

Then build the TradingView alert with Condition = your strategy, the second dropdown on Order fills only, and Trigger = Once Per Bar Close. The full field-by-field walkthrough is in Connect TradingView Alerts to Nyria → Step 4.

Converting does not fix repainting. A strategy can repaint just like an indicator. Keep process_orders_on_close=true, avoid lookahead=barmerge.lookahead_on, reference close[1] for higher-timeframe data, and validate on paper before going live. See the repainting warning.

What's next