Pine Script alert guide

Stock Trading Signals JSON Format for TradingView Alerts

A stock trading signals JSON format should be predictable for the system that receives it. Start with a small schema, keep text in double quotes, send numbers as numbers, and validate the exact payload before connecting it to any automated workflow.

A practical JSON schema

This is an illustrative schema, not a universal broker contract. Add keys only when the endpoint has a documented use for them. A JSON alert is a message contract, not an order by itself. The placeholder template must be rendered by TradingView before JSON parsing; {{close}} is not valid raw JSON.

  • symbol identifies the chart instrument
  • action uses a controlled value such as buy or sell
  • price stays numeric for downstream validation
  • signal_id names the rule version; combine it with symbol, timeframe and bar timestamp for this once-per-bar example
{
  "symbol": "{{exchange}}:{{ticker}}",
  "bar_time": "{{time}}",
  "action": "buy",
  "price": {{close}},
  "timeframe": "{{interval}}",
  "signal_id": "ema_cross_up_v1"
}

Pine Script v6 dynamic alert example

The alert() function accepts a dynamic series string. This sample waits for a confirmed bar, converts the price to text for string assembly, and leaves the resulting JSON price unquoted so the receiver gets a number. Use a standard time-based chart for this example. Select this indicator and “Any alert() function call” when creating the alert. Validate the received symbol mapping and JSON; arbitrary user text would need JSON escaping.

//@version=6
indicator("EMA signal JSON", overlay = true)

fastEma = ta.ema(close, 9)
slowEma = ta.ema(close, 21)
longSignal = ta.crossover(fastEma, slowEma)

plot(fastEma, color = color.blue)
plot(slowEma, color = color.orange)

if longSignal and barstate.isconfirmed
    payload = '{"symbol":"' + syminfo.tickerid +
      '","action":"buy","price":' +
      str.tostring(close, format.mintick) +
      ',"timeframe":"' + timeframe.period +
      '","bar_time_ms":' + str.tostring(time) +
      ',"signal_id":"ema_cross_up_v1"}'
    alert(payload, alert.freq_once_per_bar_close)

Validation and webhook safety

Validate the rendered message

Do not validate only the template. Trigger a test alert and inspect the message received after placeholders or dynamic values are resolved.

Keep credentials out of JSON

TradingView warns against putting passwords or login credentials in the webhook body. Authenticate and authorize at the receiver.

Make events idempotent

For this one-event-per-rule-per-bar example, deduplicate by rule version, instrument, timeframe and bar timestamp. A fixed signal_id alone would suppress later valid signals. Multiple events per bar need a richer event key; reconcile delivery and execution separately.

Separate signal from execution

Treat Pine Script as the signal source. The receiver remains responsible for schema checks, limits, logging, and any execution decision.

Primary references

Sources checked October 21, 2026.

Frequently asked questions

What is a stock trading signals JSON format?
It is a stable set of JSON keys used to describe a trading alert, such as symbol, action, price, timeframe, and signal ID. The receiving webhook must define what each key means before the payload is used downstream.
Should JSON prices be strings or numbers?
Send prices as JSON numbers when the receiver expects numeric values. Text fields such as symbol and action need double quotes. Validate a rendered alert because a placeholder or dynamic value can still produce invalid JSON.
Can alertcondition() create dynamic JSON?
alertcondition() accepts a constant message and can insert supported TradingView placeholders. Use alert() when the script needs to assemble a dynamic series string from calculated values.
Does a TradingView JSON alert place a trade?
No. The alert only sends a message. A separate, authenticated receiver must validate the payload and decide what to do with it. Pineify generates editable Pine Script but does not sit in the order execution path.