Ends Oct 3150% off yearly · SHIFU50
Shifu
Get started
guide

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

The minimum
{
  "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.
Entry with a resting bracket
{
  "action": "buy",
  "symbol": "MES1!",
  "quantity": 1,
  "price": 5000.25,
  "take_profit": 5010.25,
  "stop_loss": 4995.25,
  "time": "{{timenow}}"
}
A strategy you cannot edit, using TradingView’s order fills
{
  "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.