TradingView Webhook Strategies: Automate Orders From Alerts
Turn a TradingView strategy alert into a real order on one account, or on a copy group's leader so followers copy as usual.
9 min read
A webhook strategy gives you a private URL. When TradingView fires an alert, it posts a small piece of JSON to that URL, and MimikTrader places the matching order on the target you chose: a single standalone account, or a copy group's leader. Group mode then follows the normal copy pipeline — the same one your manual trades use — so every follower gets it with their own sizing and risk rules applied.

Before you start
- A MimikTrader Pro subscription. Webhook strategies are a Pro feature. Without Pro, saved strategies are kept and new entries are not traded — but close and flatten alerts always go through, so an open position is never trapped by a plan change.
- A TradingView paid plan with 2FA enabled. Webhook alerts require Essential or higher, and TradingView will not send webhooks until two-factor authentication is on.
- A target: one standalone account, or a copy group with exactly one leader. Single-account mode cannot use an account that is already a group leader or follower. Group mode places on the leader so followers copy.
- A TradingView strategy, not an indicator. This matters more than anything else on this page — see the warning below.
{{strategy.order.action}} that only exist on strategy alerts. On an indicator alert TradingView sends those placeholders through as literal text, MimikTrader cannot read an action from them, and the signal is rejected. In the alert dialog, the Condition must be your strategy — not an indicator plot.Setting it up
Most setups need no Pine script changes. Pick a Bracket on the strategy:
- My strategy's exits — MimikTrader places your entries only. When your strategy's own stop or target fills in TradingView, that fill sends its own alert and MimikTrader closes the trade. Nothing rests at your broker: if that alert is late or never arrives, the position stays open with no stop. No script changes.
- Same on every trade — MimikTrader attaches a stop and target to every entry, at distances you set once. No script changes.
- Set by each alert (advanced) — each entry carries its own stop and target from your strategy's calculations, sent in its alerts. Already sending them — for example for another copier? Keep your code and check the key names below. If not, Connect TradingView offers optional help preparing your JSON.
Choose Trade on and create your strategy
Open Webhooks and pick Single account or Copier group. Single account needs a connected account that is not in a copy group. Copier group needs a group with exactly one leader — Open Groups and click Create Group if you want followers to copy. Connecting accounts on Connections is enough for single-account mode.

Go to Webhooks in the sidebar and choose New strategy. Give it a name, pick Trade on from above, and set your order defaults — direction, size, and any take-profit or stop-loss you want attached automatically. Create strategy stays grey until both a name and that target are selected. Save. Changing or deleting a single-account assignment does not cancel broker orders or close positions — check that account before adding it to a copier group.
As soon as the strategy is created, MimikTrader opens Connect TradingView: numbered steps with your webhook URL and message, with a copy button on each. Choose My script sends JSON or Generate my message above the message to copy, then follow the three steps below for a new alert. If you ever need it again, choose Connect TradingView on the strategy — keep the URL private, since anyone who has it can send signals. Rotating the secret invalidates the old URL immediately and you will have to update the alert in TradingView.
alert(). Check the supported fields and limits below when moving an alert from another service.Creating a new alert
- 1
Select your strategy and Order fills only
For a new order-fill alert, open your chart, add your strategy to it, then press Alt + A (or use the alarm-clock icon) to create an alert. In the Condition dropdown, select your strategy. Set the trigger to Order fills only. - 2
Paste your webhook URL
In the alert dialog, open the Notifications tab. Tick Webhook URL and paste the URL from Connect TradingView. - 3
Paste the message and click Create
Copy the message for your choice into Settings → Message, then click Create. With My script sends JSON, put only{{strategy.order.alert_message}}there. Your script must supply complete JSON on every entry and exit.
Back in MimikTrader, choose View received signals to open Recent signals. Check the outcome and reason when your next alert arrives. If the row says Dispatched, Mimik sent the order toward your leader — confirm it on the leader account.
What goes in the Message box
My script sends JSON is selected by default. Use it for a Pine script that builds its own complete JSON messages. Copy just this into TradingView:
{{strategy.order.alert_message}}TradingView replaces it with the filled order's complete JSON. No surrounding JSON or extra fields go in the Message box. This option works with each bracket setting; MimikTrader still uses the size and bracket settings you selected. If your script does not build JSON, use Generate my message instead. MimikTrader remembers your message choice for this strategy in this browser.
With My strategy's exits or Same on every trade, choose Generate my message and copy that message into TradingView. It is disabled when a target or stop is set by each alert, because generated messages cannot supply each trade's target or stop. For that setup, keep My script sends JSON and optionally open Help my script send JSON. Choose Copy script-help prompt for help adding complete JSON to your script. If you want no script changes, choose one of the other two bracket settings instead.
action, symbol and id. With Bracket Set by each alert, your message must also send the bracket fields below, or entries have no target or stop. Do not add duplicate keys or a second Pine placeholder. The fields below attach a target or a stop only after Bracket is Set by each alert. Until then a test signal says alert fields ignored and names them.Let your strategy send each trade's target and stop
Set Bracket to Set by each alert. Keep your script's existing JSON and include the enabled takeProfit and stopLoss fields in each entry message. Use the distances calculated by your strategy for that trade.
- Every entry and exit needs a complete JSON object with
actionandsymbol(orticker). For a full exit, useaction: "close"or buy/sell withsentiment: "flat". - Keep complete exit JSON in
alert_messageonstrategy.close(),strategy.close_all()andstrategy.exit(). Any separatealert_profit,alert_lossoralert_trailingmessages must also be complete JSON. An exit with no message sends an empty body and cannot close the broker position. - Build actual values inside Pine. TradingView does not expand other placeholders inside
alert_message. Save script changes before creating the alert; an existing alert keeps the old version of the script.
For help preparing JSON with Set by each alert, open Help my script send JSON and choose Copy script-help prompt. Use it with your script in ChatGPT, Claude or another assistant. Save any script changes and recreate the TradingView alert so it uses the updated script.
Expand Troubleshooting / Test JSON to check a message. Testing is optional: paste an actual expanded entry message from the TradingView alert log, then test an actual expanded exit message separately. Do not test the placeholder alone; MimikTrader cannot see your Pine script. The test places no orders. Send test signalis also available from the strategy's menu.
Adding a bracket to JSON you already have
Put these keys on the same object your alert already sends. 40 and 20 are an example — use your own distances. Set Bracket to Set by each alert first, or the keys are stored on the signal and then dropped.
{
"action": "buy",
"symbol": "{{ticker}}",
"quantity": 1,
"takeProfit": { "ticks": 40 },
"stopLoss": { "ticks": 20 },
"id": "{{ticker}}-{{time}}"
}A plain number ("takeProfit": 40) means ticks when Bracket is Set by each alert. A leg can also be { "amount": 10 } (points from the entry) or { "percent": 0.5 } (percent of the entry's limitPrice or stopPrice, else the alert's price); both become whole ticks. On a dated contract you can send { "limitPrice": 5325.00 } on takeProfit and { "stopPrice": 5280.00 } on stopLoss instead. Leave a leg out and that entry has no target, or no stop. The names are takeProfit and stopLoss. tp, sl, take_profit, stop_loss, qty and contracts are not read. A test signal and a live alert both name them on Recent signals and do not use them.
ticker, sentiment ("flat" closes the position), and takeProfit / stopLoss with amount, percent or prices, and timeInForce. Not supported: the add and cancel actions, trailing stops, pnlAmount, a stopLoss type other than stop (such as stop_limit), and a quantityType other than fixed_quantity. On a continuous chart (MES1!) price legs are refused — send a distance, or a dated contract such as MESZ6. Paste one entry and one exit message your script sends into Send test signal to check.{{strategy.order.contracts}} and the other {{strategy.order.*}} placeholders are filled in only in a strategy alert's Message box. If your script builds the message inside a Pine alert() call, write the numbers into that string yourself — TradingView does not substitute placeholders there.
The fields
action— required.buy,sell,close,flattenorreverse. Be clear on the difference:closecloses the alert's symbol only, whileflattencloses every open position on the leader account — including positions from other strategies or manual trades. The aliaseslong,short,exitandflatare also accepted and mean buy, sell, close and flatten — soflatis account-wide too.symbol— required. The contract to trade.tickeris accepted as an alias, so an alert written for another platform that sendstickerworks unchanged. If both are present,symbolwins.quantity— optional whole number. For entries it is only used if your strategy takes its size from the signal, or you have turned on the size override. For a partial exit (a sell whilepositionstays long, or a buy while it stays short) the quantity sizes the reduction through the same rule as your entries — signal-sized strategies scale it by the multiplier; fixed-size strategies reduce the configured size per alert. Always capped at what the leader actually holds; omitted means close the full position.orderType— optional.market,limit,stoporstop_limit. Applies to the entry for buy/sell/reverse, and only when the entry override is enabled on the strategy; an explicitentryTypefield wins over it. It is deliberately ignored on close and flatten — your exit stays on the strategy's configured exit type, so a stray field can never turn a guaranteed market close into one that waits on a price. To change the exit type from an alert, use the explicitexitTypefield (with apricefor non-market exits).price— required when your entry type is Limit, Stop or Stop-limit (unless the alert sendslimitPrice/stopPrice). A Market entry needs it only to measure apercentleg, and on Tradovate when one leg is in ticks and the other is a price. Send{{close}}then, or the entry is refused.takeProfit/stopLoss— optional; what they do depends on each leg's source on the strategy (see below). Either a plain number or an object naming its own unit:{ "ticks": 40 }for a tick offset,{ "amount": 10 }in points,{ "percent": 0.5 }of the entry's price,{ "limitPrice": 5325.00 }for an absolute take-profit price, or{ "stopPrice": 5280.00 }for an absolute stop price. Note the absolute key is specific to the leg —limitPricebelongs to takeProfit andstopPriceto stopLoss. What the values do depends on the leg's source on the strategy. On a configured leg they retune it — and only when the matching override is enabled; they do not add protection to a leg that is off. A plain number there is read in the leg's configured unit. Set Bracket to Set by each alert, or set that leg to Set by each alert in More settings, and the alert's field is the leg: sent, it attaches; omitted, there is no such leg — and a plain number is always ticks. If an order is placed while alert fields like these were ignored, the Recent signals row says which. One constraint when mixing units: if one leg is in ticks and the other is an absolute price, the alert must carry aprice(so a market entry with mixed units is rejected) — keep both legs in the same unit on market entries.position— optional. TradingView's{{strategy.market_position}}after the fill.flatturns a buy or sell into a close.longorshortthat opposes the leader's live position is treated as a reverse — so a long-only strategy still closes the long when the chart flips short, and does not open the new short. A sell while the position stayslong(or a buy while it staysshort) is a partial exit: the leader is reduced, never rejected. Note the reduction applies to the leader's whole position in that market — same as close and flatten — and any resting stop or target keeps its original size until it is modified or replaced.id— recommended. A unique id per alert. MimikTrader uses it so a TradingView 5xx retry cannot place the same order twice. The generated id uses bar{{time}}, not wall-clock{{timenow}}, so a retry of the same fill keeps the same id. If you leaveidout, we key on the bartimewhen your JSON includes it — a retry of the same alert then always matches, and two id-less alerts for the same symbol, action and bar count as one, so a strategy that adds more than once per bar must send anid. With neither field we fall back to a 10-second fingerprint: alerts for the same symbol and action inside 10 seconds are treated as one, and a TradingView retry landing past a 10-second boundary can slip through — sendidortimeto close that.time— optional. The bar time, i.e. TradingView's{{time}}placeholder. If you are not sending anid, the bar time becomes the duplicate key: a retry of the same alert always matches it, and two different bars are never mistaken for a duplicate. Do not use{{timenow}}here or inid— it renders a fresh wall-clock value each time it is evaluated, so it cannot serve as a stable duplicate key.test— optional. Sendtrueto dry-run the webhook: the signal runs every intake check — authentication, rate limit, payload parsing, strategy enabled, trading window, direction filter, group target — then stops before dispatch and shows up under Recent signals as Skipped with the reason test signal. If the payload also carries fields the strategy would drop — a quantity on a fixed-size strategy, TP/SL its protection source cannot use — the reason reads test signal; alert fields ignored: … and names them, so a green test never implies a bracket or size the strategy cannot honour. It proves the pipe, not the trade: broker connection, contract resolution, subscription and risk checks are not exercised, so a green test can still be followed by a failed live order for those reasons. Test posts count toward the strategy's rate limit.secret— optional, and not included in the generated JSON. Authentication is the webhook URL. If you addsecretyourself it must match; a mismatch is rejected as not found. TradingView's own docs warn against putting credentials in the alert message.
Contract symbols and roll
Leave {{ticker}} in place to trade yesterday's most active month on CME Globex. TradingView often sends a continuous symbol such as GC1! or MES1!. We pick that volume leader and place it. Use a market entry; stops and targets as ticks from the fill. This is usually the TradingView continuous, not a guarantee it is the chart underfoot or the deepest book this second.
To trade the contract on the chart, your Pine script must evaluate syminfo.current_contract and write the resulting dated name into the alert message. Customers cannot paste the literal text syminfo.current_contract into ordinary webhook JSON and expect TradingView to substitute it. {{ticker}} is the chart ticker (often GC1!), not that Pine field.
For an exact expiry, put GCZ2026 or MESM6 in the JSON. Limit and stop prices (entry or exit) only work with a dated contract. If the liquid month cannot be resolved, MimikTrader fails closed and records the reason rather than guessing.
A continuous GC alert will not open December while September is still on. Close the old GC month first (market close of GC1!, or dated GCU6). Flatten closes every product on that leader, not just gold. Reverse of GC will not run if two GC months are open; it reopens the month you just closed. Digit-leading FX such as 6E is still unsupported. On a broker we have not proven for this path, a new GC / GC1! entry is rejected; dated GCZ2026 still works.
How sizing is decided
Two settings work together, and both always apply:
- Size quantity — the base number of contracts (or, in Signal quantity mode, the size that came from the alert).
- Signal quantity multiplier — multiplied on top of that base. Results are rounded up to whole contracts, so a base of 3 with a 0.4 multiplier places 2.
For fixed sizing, the strategy card shows the resulting size in plain terms — for example Size 1 × 3 = 3 contracts — so what you see is what will be placed. In Signal-quantity mode the base comes from each alert, so the card shows the multiplier that will be applied to it (for example Signal quantity × 2). Follower accounts then apply their own multiplier on top, as they do for any copied trade.
If you do not have a strategy yet
You need a TradingView strategy on the chart — an indicator alert will not fill the placeholders. If you do not already have one, paste this timer script into Pine Editor, add it to a 1-minute chart (MES1! or MNQ1! is fine), then create the alert on that strategy. On a 1-minute chart it flips about every two minutes: buy 1 when flat, close when long.
//@version=5
strategy("Mimik webhook timer test", overlay=true,
default_qty_type=strategy.fixed, default_qty_value=1,
process_orders_on_close=true, calc_on_every_tick=false,
pyramiding=0)
// On a 1-minute chart this flips about every N minutes.
minutesBetweenFlips = input.int(2, "Minutes between flips", minval=1, maxval=30)
shouldFlip = (bar_index % minutesBetweenFlips) == 0
// Complete JSON for each order; the alert Message uses one placeholder.
entryMessage = '{"action":"buy","symbol":"' + syminfo.ticker + '","quantity":1,"id":"' + syminfo.ticker + '-' + str.tostring(time) + '-entry"}'
exitMessage = '{"action":"close","symbol":"' + syminfo.ticker + '","quantity":1,"id":"' + syminfo.ticker + '-' + str.tostring(time) + '-exit"}'
if shouldFlip and strategy.position_size == 0
strategy.entry("TimerLong", strategy.long, alert_message=entryMessage)
else if shouldFlip and strategy.position_size > 0
strategy.close("TimerLong", alert_message=exitMessage)Then follow the three setup steps above. Condition = Mimik webhook timer test. Paste the webhook URL on Notifications. This script sends complete JSON on both entries and exits. Keep My script sends JSON selected and paste only {{strategy.order.alert_message}} into Message, just like the default setup above. Use Bracket My strategy's exits or Same on every trade: this sample supplies no target or stop fields. After the first flip, choose View received signals — then turn the alert off.
Alert frequency and lifetime
- Set the frequency in your strategy code. Strategy alerts fire when the strategy generates an order, so avoid intrabar signals unless you intend to trade them.
- TradingView alerts expire after a period depending on your plan. If your signals stop arriving with no rejection rows in MimikTrader, check whether the alert expired.
- Keep the URL private. Anyone who has it can send signals to your strategy. Rotate the secret if you think it has leaked.
When something does not arrive
Expand the strategy and read Recent signals first. Most problems show up there with a reason attached:
- Create strategy is grey — you have not picked Trade on yet. Choose a standalone account, or a copy group with exactly one leader. Connecting accounts on Connections does not count as a group. For copier-group mode, Open Groups, create a group, set one leader, then pick that group on the webhook form.
- No row at all — the post never authenticated. The URL is wrong or the secret has been rotated, the strategy was deleted, or the same alert was already received (a duplicate). Re-copy the URL from the strategy and re-paste it into TradingView.
- Failed, with a payload message — the JSON was not understood. The usual cause is an indicator alert, or TradingView's default plain-text message left in place.
- Skipped — the signal was understood but deliberately not traded: the strategy is disabled, it is outside your trading window, the direction is not allowed, the group is not active, the single-account assignment was removed or retargeted before dispatch, your subscription no longer includes webhook strategies (the reason reads entitlement: entry suppressed — closes and flattens still go through even then), Ignore exit alerts dropped an exit or a derived flip, or it was a test signal dry run. The reason column says which. Changing the assignment does not cancel broker orders or close positions.
- Dispatched — Mimik sent the order toward your leader. Confirm the order on the leader account. From that point it behaves like any other trade, so if a follower did not get it, the answer is in that follower's risk settings or connection state. When the alert carried fields the strategy is configured to ignore, the reason names them — alert fields ignored: … — so a dispatched row that went in flat is never mistaken for one whose bracket attached.
If TradingView shows “Timeout exceeded” but Recent signals shows a row — trust the row's status, not TradingView. TradingView cancels a webhook if the receiving server has not replied within three seconds, and it writes that error whether or not the server went on to accept the alert. So read the row: Dispatched means we really did place the order — re-entering it by hand doubles your position. Failed or Skipped means we did not place it. Pending or Processing means it is still queued — wait and refresh before acting either way.
The reverse is also worth knowing: TradingView does not retry a timeout. It only re-sends when the server answers a 5xx error (other than 504), and then at most three times. So a timeout with no row here usually means that alert is gone — it will not arrive later. One more no-row case: a duplicate-suppressed post (an id we have already seen, or an id-less alert matching an earlier one on the same bar) is answered 200 and deliberately leaves no row — the original alert's row is the record.