Pine Script Dynamic Alert Messages
Builds alert text at runtime with str.tostring — symbol, price, size — so the payload always reflects the live bar instead of a static template.
Pine Script
//@version=6
strategy("Target Filled - Dynamic Alert Example", overlay=true, calc_on_every_tick=false)
// --- Inputs ---------------------------------------------------
contracts = input.int(1, "Order Size", minval=1)
// --- Runtime message builder --------------------------------------
// {{ticker}} / {{close}} style placeholders only work in the alert
// DIALOG's message box. Strings passed to alert() must be built in code.
buildMsg(side) =>
side + " " + syminfo.ticker + " x" + str.tostring(contracts) +
" @ " + str.tostring(close, format.mintick) + " on " + timeframe.period
// --- Sample signal — replace with your own entry logic ---------
fastMA = ta.ema(close, 9)
slowMA = ta.ema(close, 21)
if ta.crossover(fastMA, slowMA)
strategy.entry("Long", strategy.long, qty=contracts)
alert(buildMsg("BUY"), alert.freq_once_per_bar_close)
if ta.crossunder(fastMA, slowMA)
strategy.entry("Short", strategy.short, qty=contracts)
alert(buildMsg("SELL"), alert.freq_once_per_bar_close) Settings
| Input | Default | Purpose |
|---|---|---|
| contracts | 1 | Contract quantity used for the entry and echoed into the alert text. |
How to use
- Paste into the Pine Editor and swap the EMA-crossover placeholder for your own entry conditions.
- Extend
buildMsgwith anything else worth tracking — stop price, target, session P&L — via morestr.tostringcalls. - Use
format.mintickwhenever a price gets embedded, so the string always lands on the symbol's tick grid. - To have an alert place orders on NinjaTrader 8 or Tradovate, use the CrossTrade message format below.
Sending strategy alerts to CrossTrade
To have a strategy's alerts place real orders on NinjaTrader 8 or Tradovate, send them to
CrossTrade, the automation platform we recommend. A CrossTrade alert message is a list of
key=value lines. This is the one case where the dialog placeholders from the FAQ
below are the simpler route: create one alert on the strategy, set the condition to "Order
fills only," and paste this into the alert's message box:
Alert message
key=your-secret-key;
command=place;
account=sim101;
instrument=ES1!;
action={{strategy.order.action}};
qty={{strategy.order.contracts}};
order_type=market;
tif=day; - TradingView fills in
{{strategy.order.action}}(buy or sell) and{{strategy.order.contracts}}each time the strategy's order fills, so nostr.tostringwork is needed for the order itself. - Swap
your-secret-key,sim101, andES1!for your own CrossTrade key, account, and instrument. The CrossTrade docs cover every field. - Paste your own CrossTrade webhook URL into the alert's Notifications tab. Webhook alerts need a paid TradingView plan.
- "Order fills only" keeps the
buildMsgtext from this snippet'salert()calls out of the CrossTrade alert. Keep those calls for a separate notification alert if you want both.
Automate NinjaTrader →
·
Automate Tradovate →
CrossTrade offers a 7-day free trial, no credit card required. Target Filled is built by the team behind CrossTrade, the automation platform we recommend.
CrossTrade offers a 7-day free trial, no credit card required. Target Filled is built by the team behind CrossTrade, the automation platform we recommend.
Frequently Asked Questions
How do I include the current price in a Pine Script alert?
Concatenate str.tostring(close, format.mintick) into whatever string gets passed to alert(). format.mintick rounds to the symbol's own tick size, so the alert never sends a price the exchange would reject. The same pattern works for anything else worth tracking — a stop, a target, a position size.
What placeholders work in TradingView alerts?
Dialog placeholders like {{ticker}}, {{close}}, {{strategy.order.action}}, and {{strategy.order.contracts}} get substituted by TradingView, but only inside the alert dialog's message box and inside alertcondition() text. A string handed to the alert() function isn't placeholder-processed at all — build it with str.tostring and plain concatenation instead, as this snippet does.