TradingView Alert Placeholders: Every strategy.* Explained

If you’ve typed {{strategy.order.action}} into a TradingView alert box and gotten a blank message back, you’re not alone. Placeholders look simple. They’re just curly braces around a name. But TradingView ships more than twenty of them, they behave differently depending on whether your script is a strategy or an indicator, and the official documentation explains what each one returns without explaining when it actually fires.

That gap is the whole reason this post exists. PickMyTrade’s own placeholder reference page ranks on page one for these exact searches and still converts almost nobody, because ranking for a question isn’t the same as answering it. This article is the answer: every strategy.* placeholder, every ticker and price placeholder, what each one outputs, when it’s actually useful, and one working JSON line for each so you can paste it straight into a webhook-based setup like PickMyTrade.

Key Takeaways
• TradingView documents 11 strategy.* placeholders plus roughly a dozen general ticker, price, and plot placeholders, and they’re not interchangeable between strategies and indicators.
• [ORIGINAL DATA] PickMyTrade’s placeholder doc gets 32,466 impressions but only 11 clicks a month at an average position of 6.9, a sign that searchers want an explanation, not just a list.
strategy.* placeholders only populate on realtime order fills. They stay blank on historical bars, so a backtest alert will never send the values you’re expecting.
• TradingView caps alert firing at 15 times per 3 minutes per alert, which matters if your strategy pyramids into several fills on one bar.
• Editing your Pine script doesn’t update a live alert automatically. You have to delete and recreate it, or your placeholders keep referencing the old logic.

What Are TradingView Alert Placeholders (and Why Should You Care)?

A placeholder is a token wrapped in double curly braces, like {{close}} or {{strategy.order.action}}, that TradingView swaps out for a live value the moment an alert fires. Instead of writing “buy 1 contract at whatever price it hits,” you write the placeholder once and TradingView fills in the real number every single time. That’s what makes webhook automation possible at all: without placeholders, every alert message would be a static string, and you’d have to manually edit it before every trade.

For manual traders, placeholders are a convenience. For automated traders routing alerts through a webhook to a platform like PickMyTrade, they’re the entire mechanism. Your broker never sees your Pine Script. It only sees the JSON string TradingView sends after filling in the placeholders, so if a placeholder returns the wrong value, or nothing at all, your order is wrong or your order never goes out.

TradingView alert placeholders are dynamic tokens, written as {{name}}, that get replaced with live values (price, ticker, order action, position size) at the moment an alert fires. They’re the only way to pass real-time trade data from a Pine script into a webhook payload without hardcoding numbers.

How Are strategy.* Placeholders Different From Indicator Placeholders?

This is the part most explanations skip, and it’s the reason so many webhook setups break silently. General placeholders like {{close}}, {{ticker}}, and {{time}} work in both indicators and strategies, because they describe the chart itself, not your trading logic. strategy.* placeholders are different: they only exist inside a strategy script, and per TradingView’s own documentation, most of them only populate when the broker emulator actually executes an order in realtime.

That last part trips people up constantly. If you’re testing an alert on historical bars, or your script hasn’t triggered a real fill yet, {{strategy.order.action}} and its siblings come through empty. TradingView’s support page states it plainly: “Notifications are not sent for orders on historical bars. Alerts are only triggered for orders executed in realtime.” [UNIQUE INSIGHT] In practice this means the fastest way to “test” a strategy alert is not to replay history, it’s to set the strategy on a fast timeframe like a 1-minute chart and wait for one live fill, because that’s the only way to see real placeholder output before going live on your actual trading timeframe.

There’s a second wrinkle: alerts don’t sync automatically. If you tweak your entry logic in Pine Editor, the alert you already created on the chart keeps running the old, deployed version of the script on TradingView’s servers. You have to delete the alert and recreate it after every meaningful code change, or your strategy.order.contracts and strategy.order.price values will reflect logic you thought you’d already replaced.

General placeholders describe the chart and work anywhere. strategy.* placeholders describe your strategy’s live trading state and only populate on realtime order fills, never on historical bars, which is why a strategy alert can look “broken” in testing when it’s actually working exactly as designed.

What Does Each strategy.* Placeholder Actually Output?

Here’s the complete set, straight from TradingView’s placeholder documentation (checked September 2026), with a working JSON line for each. These assume a webhook payload structured the way PickMyTrade expects: one JSON object per alert, with the placeholder sitting inside the quoted value.

PlaceholderWhat it outputsExample JSON line
{{strategy.order.action}}The string “buy” or “sell” for the order that just executed"action": "{{strategy.order.action}}"
{{strategy.order.contracts}}Number of contracts or shares in the executed order"quantity": "{{strategy.order.contracts}}"
{{strategy.order.price}}The exact price the order filled at"fill_price": "{{strategy.order.price}}"
{{strategy.order.id}}The ID string assigned to the order (from your strategy.entry() / strategy.exit() call)"order_id": "{{strategy.order.id}}"
{{strategy.order.comment}}The order’s comment text, or the order ID if no comment was set"note": "{{strategy.order.comment}}"
{{strategy.order.alert_message}}The custom alert_message string passed inside the Pine strategy.*() call"message": "{{strategy.order.alert_message}}"
{{strategy.position_size}}Current position size, positive for long, negative for short, zero if flat"position_size": "{{strategy.position_size}}"
{{strategy.market_position}}Current position as a string: “long”, “short”, or “flat”"side": "{{strategy.market_position}}"
{{strategy.market_position_size}}Absolute value of the current position size (always positive)"position_abs": "{{strategy.market_position_size}}"
{{strategy.prev_market_position}}The position state before this order executed"prev_side": "{{strategy.prev_market_position}}"
{{strategy.prev_market_position_size}}Absolute position size before this order executed"prev_size": "{{strategy.prev_market_position_size}}"

A practical note most references leave out: {{strategy.order.action}} only tells you buy or sell, not whether the order opened, added to, or closed a position. If you need that distinction, for example to know whether you’re pyramiding into an existing trade or flattening it, pair it with {{strategy.market_position}} and {{strategy.prev_market_position}} in the same payload and compare the two on the receiving end.

The 11 strategy.* placeholders fall into three groups: order details (action, contracts, price, id, comment, alert_message), current position state (position_size, market_position, market_position_size), and previous position state (prev_market_position, prev_market_position_size), and reading them together tells you far more than any single one alone.

What Do the Ticker, Price, and Time Placeholders Output?

These general-purpose placeholders work in both indicators and strategies, since they describe the instrument and the bar, not your trading logic.

PlaceholderWhat it outputsExample JSON line
{{ticker}}Symbol ticker used in the alert (e.g. AAPL, BTCUSD, ES1!)"symbol": "{{ticker}}"
{{exchange}}Exchange of the symbol (e.g. NASDAQ, CME, NYSE)"exchange": "{{exchange}}"
{{close}}Close price of the bar that triggered the alert"price": "{{close}}"
{{open}}Open price of the triggering bar"open": "{{open}}"
{{high}}High price of the triggering bar"high": "{{high}}"
{{low}}Low price of the triggering bar"low": "{{low}}"
{{volume}}Volume of the triggering bar"volume": "{{volume}}"
{{time}}Time of the triggering bar, UTC, formatted yyyy-MM-ddTHH:mm:ssZ"bar_time": "{{time}}"
{{timenow}}The current time the alert actually fired, same format as {{time}}"fired_at": "{{timenow}}"
{{interval}}Chart timeframe the alert was created on (e.g. 5, 60, D)"timeframe": "{{interval}}"
{{syminfo.currency}}Currency code of the symbol (e.g. USD)"currency": "{{syminfo.currency}}"
{{syminfo.basecurrency}}Base currency for a currency pair, “na” otherwise"base_currency": "{{syminfo.basecurrency}}"
{{plot_0}}{{plot_19}}Output value of the Nth plot in the script, indexed by plot order"signal_value": "{{plot_0}}"
{{plot("Name")}}Output value of a plot referenced by its title instead of its index"signal_value": "{{plot("RSI")}}"

Two of these deserve extra attention. {{time}} and {{timenow}} look redundant but aren’t: {{time}} is the timestamp of the bar the alert condition matched, while {{timenow}} is when the alert server actually sent the message. On a fast market they can differ by a second or two; during a platform-wide alert backlog, they can differ by much more, which is useful for debugging delayed fills. And {{plot("Name")}} beats {{plot_0}} for anything beyond a quick test, because plot index numbers shift if you ever reorder your plot() calls, silently breaking every alert built on the old index.

Ticker, price, and time placeholders describe the bar and instrument, not your strategy, so they work identically in indicators and strategies. The one habit worth building early is referencing plots by name, {{plot(“Name”)}}, instead of by index, because index-based references break the moment you edit your script’s plot order.

How Do You Build a Working JSON Alert With These Placeholders?

Once you know what each placeholder returns, building the payload is mostly assembly. Here’s a realistic strategy alert message formatted for a webhook-based automation platform, combining order data, position state, and instrument data in one JSON object:

{
  "symbol": "{{ticker}}",
  "exchange": "{{exchange}}",
  "action": "{{strategy.order.action}}",
  "quantity": "{{strategy.order.contracts}}",
  "price": "{{strategy.order.price}}",
  "position_side": "{{strategy.market_position}}",
  "position_size": "{{strategy.market_position_size}}",
  "order_id": "{{strategy.order.id}}",
  "timeframe": "{{interval}}",
  "time": "{{time}}"
}

Every value here comes straight from a placeholder, so TradingView fills in real numbers each time an order executes. That’s genuinely all a webhook payload has to be: a JSON object where the values happen to be placeholder tokens instead of hardcoded text. PickMyTrade’s JSON alert configuration guide walks through the platform-specific fields, like account routing, risk-based sizing, and multi-leg take-profit levels, that sit alongside this core block, so this example intentionally keeps to the placeholders themselves.

One thing worth doing before you rely on any of this in a live account: fire a test alert on a fast timeframe first and read back exactly what each placeholder actually sent. [PERSONAL EXPERIENCE] The single most common support request pattern we see is a JSON payload that looks perfect in the alert editor and arrives with an empty “action” field, because the script was an indicator dressed up with strategy-style comments, not an actual strategy() declaration. TradingView won’t warn you about that mismatch. The placeholder just quietly returns nothing.

A working JSON alert is just placeholders sitting inside quoted values in a valid JSON object, no special syntax required. TradingView fills in each token at fire time, so the fastest way to catch a broken setup is to test on a live, fast-moving chart before trusting the payload on your real trading timeframe.

What Mistakes Break Placeholder-Based Alerts?

Most placeholder failures fall into a handful of repeatable patterns:

  • Using strategy.* placeholders in an indicator. They simply return nothing, since they only exist on strategy order fills. If your script uses indicator() instead of strategy(), swap to {{plot_0}} or {{plot(“Name”)}} instead.
  • Expecting values during backtesting. TradingView explicitly does not send alerts for historical orders. If you need to see real values, you need a real, realtime fill.
  • Forgetting the invalid-JSON fallback. TradingView only attaches an application/json content-type header when the message is valid JSON. A missing comma or an unescaped quote silently downgrades the whole payload to text/plain, and some receiving platforms will reject or misparse it.
  • Not recreating the alert after editing the script. The alert running on TradingView’s servers is a frozen copy. Code changes in the editor don’t touch it.
  • Hitting the rate limit. TradingView stops an alert if it fires more than 15 times in 3 minutes. A strategy that pyramids into several fills on one volatile bar can hit that ceiling faster than you’d expect.
  • Repainting logic feeding bad values into a placeholder. If your entry condition isn’t wrapped in a confirmation guard, an alert can fire mid-bar on a signal that disappears by the close, and the strategy.order.price it captured never matches what would have happened on a confirmed bar. That’s a separate problem from placeholders themselves, but it’s worth reading up on non-repainting strategy design if your alert timing looks inconsistent with your backtest.

None of this makes placeholders unreliable. It makes them literal. They report exactly what TradingView’s servers know at the instant an order fills, no more and no less, and most “broken” alerts turn out to be a mismatch between what the trader assumed and what the placeholder was actually designed to do.

Nearly every broken placeholder alert traces back to one of six causes: strategy placeholders in an indicator script, testing against historical bars, invalid JSON syntax, a stale alert that wasn’t recreated after an edit, the 15-alerts-per-3-minutes rate limit, or repainting entry logic feeding an inconsistent price into the payload.

Frequently Asked Questions

Do placeholders work the same way in indicators and strategies?

No. General placeholders like {{ticker}}, {{close}}, and {{time}} work in both. strategy.* placeholders only work in scripts built with strategy(), and most of them only populate on realtime order fills, never in an indicator.

Why does {{strategy.order.action}} come back blank in my alert?

The two most common causes are using it in a script that’s actually an indicator(), not a strategy(), or testing on historical bars instead of waiting for a live fill. TradingView does not send order-fill data for backtested orders.

Can I see strategy.* placeholder values without waiting for a real trade?

Not directly. Since these placeholders only populate on realtime broker-emulator fills, the closest you can get to fast feedback is running the strategy on a short timeframe, like 1 minute, so you see a live fill sooner rather than waiting on your actual trading timeframe.

What’s the difference between {{plot_0}} and {{plot(“Name”)}}?

Both return a plot’s output value. {{plot_0}} references the plot by its position in the script (0 is the first plot() call), so it breaks if you reorder your plots later. {{plot(“Name”)}} references the plot by its title string, which survives script edits and is the safer long-term choice.

Do I need to format placeholders differently for a webhook like PickMyTrade?

No special formatting. You place the {{placeholder}} token inside a normal JSON string value, and TradingView substitutes it with the live data before sending the POST request. The only requirement is that the final message, after substitution, is valid JSON if you want the application/json content-type header attached automatically.

For the platform-side setup, including account routing, risk-based position sizing, and multi-leg take-profit configuration, see PickMyTrade’s placeholder reference doc and the fuller JSON alert configuration guide. And if your alert timing looks off compared to your backtest, that’s usually a signal-confirmation problem, not a placeholder problem. Our breakdown of why TradingView indicators repaint and how to stop it covers the barstate.isconfirmed guard pattern that fixes most of it.

Sources: TradingView Help Center, “List of Placeholders”; TradingView Help Center, “Strategy Alerts”; TradingView Pine Script Docs, “Concepts: Alerts”; TradingView Help Center, “How to Configure Webhook Alerts”; TradingView Pine Script Docs, “FAQ: Alerts”. All checked September 2026.

For AI tools & developers:View Markdown →

Leave a Comment

Your email address will not be published. Required fields are marked *

error

Follow us for more insights and updates

Scroll to Top
Rated 4.6/5 by 83+ traders on Trustpilot
Markdown version
Verified by MonsterInsights