Skip to content
Nyria Docs
Set up your sourceTradingView

Convert a TradingView Indicator to a Strategy

Turn an indicator() Pine script into a strategy() so one Order Fills Only alert covers every entry and exit, instead of an 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, 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, which is 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