TradingView alert JSON: the fields that matter
Short answer
A Shifu alert is one JSON object with three required fields — action, symbol and time — and optional fields for size, order type, prices, a resting take-profit and stop, a trailing stop, and TradingView’s position placeholders. Leave out any leg you do not want; a field that is present must hold a real value. Ready-made messages on the bot’s Setup tab carry all of this for you.
Updated: September 25, 2026
{
"action": "buy",
"symbol": "MES1!",
"quantity": 1,
"time": "{{timenow}}"
}actionrequiredbuy · sell · close · exit · reverse- What to do. buy and sell enter in that direction. On paper and Tradovate accounts a new entry first closes the position already open in that contract. The one exception is a strategy adding to a trade it already holds: when that alert carries the position and size lines of the ready-made strategy message, Shifu adds to what the account holds instead (see “A new entry replaces the old position on paper and Tradovate” under Brokers). On Rithmic accounts an entry is sent as it is, so it adds to, reduces or flips what is open. A partial exit (a strategy taking part of its position off) is not an entry when the alert carries the position lines of the ready-made strategy message: with its two size lines, paper and Tradovate accounts take the same share off where they can, and Rithmic accounts keep the full size until the strategy’s full exit; without the size lines, nothing is sent. Without the position lines, Shifu cannot tell a partial exit from an entry, so it is sent as an entry. close and exit both flatten your position in that symbol. reverse asks to flip an open position to the other side — see the broker notes below, because reverse is not accepted on every account type.
symbolrequireda futures contract, e.g. MES1!- Which contract to trade. Use the TradingView continuous form (MES1!, MNQ1!) and Shifu resolves it to the current front month for you, so you never have to edit an alert at rollover. A dated contract works too, but stops working once it expires.
timerequired{{timenow}}- When the alert fired. It is how Shifu tells a repeat of the same alert from a new one: an exact repeat is treated as one alert, so a retriggered or double-delivered alert cannot fill twice. Keep it on its own line, exactly as the ready-made message has it. TradingView’s message check cannot read a {{word}} that is glued to other text.
order_idoptional{{strategy.order.id}}- Strategy alerts only. TradingView’s own name for the order: it tells two different fills in the same bar apart. Leave it out on an indicator alert: the action (buy, sell, exit) does that job there.
idempotency_keyoptionalany text up to 512 characters- For your own scripts only: a unique id you build yourself. When it is present it is used instead of time and order_id. The ready-made messages do not use it.
quantityoptionalwhole number, 1 to 10,000- How many contracts the alert is asking for. Used when the bot is set to size from the alert. Left out, the bot’s Default size is used instead. Each account can still scale or override this on the Account routing tab.
order_typeoptionalmarket · limit · stop · stop_limit- How the entry goes to market. Defaults to market when you leave it out.
limit_priceoptionala price- The limit price for the entry. Required whenever order_type is limit or stop_limit — the alert is refused without it.
stop_priceoptionala price- The trigger price for the entry. Required whenever order_type is stop or stop_limit — the alert is refused without it.
priceoptionala price- Where your chart was when the alert fired. It is a reference, never a constraint: a market order still fills at market. Shifu uses it to price paper fills honestly and to place bracket levels exactly where your chart computed them, so include it whenever your script can.
take_profitoptionala price- An absolute price for a resting take-profit. When present, Shifu places it at the broker as a limit order the moment the entry fills. Leave the field out entirely if you do not want this leg.
stop_lossoptionala price- An absolute price for a resting stop. Placed at the broker alongside the take-profit; a fill on either one cancels the other. Leave the field out entirely if you do not want this leg.
trail_distanceoptionala distance in the symbol’s price units- How far behind the best price the stop should follow. Including this field turns the stop leg into a trailing stop at the broker instead of a fixed one. Your initial stop still sits exactly where stop_loss put it, so your opening risk always matches your plan.
trail_triggeroptionala distance in the symbol’s price units- How far price must move in your favour before the trail starts following. Leave it out to trail from entry. Honoured on Tradovate and Rithmic; simulated on paper.
market_positionoptionallong · flat · short- Where TradingView says the strategy stands after this order. This is what makes a strategy you cannot edit fully automatable: a bare buy or sell that leaves the strategy flat is read as a close.
prev_market_positionoptionallong · flat · short- Where the strategy stood before this order. Paired with market_position, a straight flip from long to short (or back) is read as a reverse rather than a plain entry.
metaoptionalany JSON object- Anything else you want kept with the alert — a setup name, a tag, a note. Shifu stores it with the record so you can see it later. It never changes routing.
{
"action": "buy",
"symbol": "MES1!",
"quantity": 1,
"price": 5000.25,
"take_profit": 5010.25,
"stop_loss": 4995.25,
"time": "{{timenow}}"
}{
"action": "{{strategy.order.action}}",
"symbol": "{{ticker}}",
"quantity": "{{strategy.order.contracts}}",
"market_position": "{{strategy.market_position}}",
"prev_market_position": "{{strategy.prev_market_position}}",
"position_size": "{{strategy.market_position_size}}",
"prev_position_size": "{{strategy.prev_market_position_size}}",
"time": "{{timenow}}",
"order_id": "{{strategy.order.id}}"
}Already formatted for another service? Shifu also reads messages made for PickMyTrade and TradersPost, and JSON that carries an action, a symbol and a time, and translates them to the fields above, with limits. From a PickMyTrade message it reads dollar_tp and dollar_sl as points from the alert price; a stop or target sent as tp, sl, percentage_tp or percentage_sl is not read. From a TradersPost message it reads the ticker, the action (buy, sell or exit), a quantity in contracts and a take-profit and stop given as prices, and it enters at market; sentiment, amounts or percents, trailing stops and limit or stop entries are not read. When a message leans on a part Shifu does not read, paste the ready-made message from the bot’s Setup tab.
Questions people ask
Do I have to write the JSON myself?
No. Every ready-made message lives on the bot’s Setup tab, pre-filled with your ticker and size. Copy it rather than retyping it — a stray character is the most common reason an alert is refused.
What are time and order_id for?
They tell a repeat of the same alert from a new one, so a retriggered or double-delivered alert cannot fill twice. Use "time": "{{timenow}}" on every alert. On a strategy alert add "order_id": "{{strategy.order.id}}". Keep each one on its own line: TradingView’s message check cannot read a {{word}} that is glued to other text. If you build your own unique id in a script, you can send it as idempotency_key instead.
Which placeholders can I use?
TradingView’s own: {{timenow}} for the time line, {{close}} for a price such as a limit entry at the bar’s close, {{ticker}} for the symbol, and on strategy order-fill alerts the {{strategy.*}} fields for action, contracts and position. Indicator alerts cannot fill strategy placeholders.
Why include price if a market order fills at market anyway?
It is a reference, never a constraint. Shifu uses it to price paper fills honestly and to place bracket levels — including ticks, points or dollars from the entry — exactly where your chart computed them.
