How to send TradingView alerts to a broker through a webhook
A relay turns a TradingView alert into an order. What breaks is the JSON, the bar the alert fires on, the duplicate, and a size meant for the chart.
Create the alert on a paid TradingView plan with two-factor authentication on, paste a relay's webhook URL into it, and write the message in the JSON that relay expects: TradersPost reads ticker and action, SignalStack symbol, action and quantity. Run it on paper first. What breaks is an alert that fires mid-bar, a duplicate that becomes a second order, a quantity sized for the chart rather than your account, and seconds of delay.
The short way
Four pieces, in this order:
- A TradingView alert on a paid plan. The pricing page leaves Webhook notifications unticked for the free Basic plan and ticks it from Essential up, and the help page says webhook alerts are only allowed when two-factor authentication is on. Without 2FA the field is there and nothing is sent.
- A relay's webhook URL pasted into the alert's Notifications tab.
- A message in the relay's own JSON, written into the alert's Message box with TradingView's placeholders filling in the values at fire time.
- A broker connected at the relay — a paper account first.
The message is the part people get wrong, because each relay reads its own field names. For
TradersPost, the signal reference requires ticker and action (buy,
sell, exit and a few more), and takes TradingView's strategy position as sentiment:
{
"ticker": "{{ticker}}",
"action": "{{strategy.order.action}}",
"sentiment": "{{strategy.market_position}}",
"price": "{{close}}"
}
For SignalStack, the help page's strategy example names the instrument
symbol instead and carries a quantity:
{ "symbol": "{{ticker}}", "action": "{{strategy.order.action}}", "quantity": "{{strategy.order.contracts}}" }
The same alert sent to the wrong relay is not an order with a missing field — it is an error, or
nothing. TradingView's placeholders are documented on its help page: {{ticker}}, {{close}}
and {{time}} for the bar the alert fired on, {{timenow}} for the moment it fired, and for
strategies {{strategy.order.action}} (buy or sell), {{strategy.order.contracts}},
{{strategy.order.id}} and {{strategy.market_position}} (long, flat or short).
What the options are
A relay priced per account. TradersPost connects 16 brokers and
exchanges and charges by connected accounts and asset classes, from $49 a month, with no
per-order fee. Its webhook takes 60 requests a minute and 500 an hour, and it does not support
strategies on charts below one minute. Leave quantity out and its docs say the size is
calculated or defaults to 1; the subscription settings decide whether the signal's quantity is
used at all.
A relay priced per order. SignalStack meters orders delivered to a live
account — 5 a month free, 50 for $27 — and never meters paper ones, which makes it the cheapest
place to leave a configuration running on paper for weeks. Fields and allowed actions are listed
per broker: its tastytrade stock page accepts buy, sell, close and the four open/close
variants. Which of the two costs less for your alert count is worked out in
TradersPost vs SignalStack.
A relay built around futures accounts. PickMyTrade is $50 a month per broker login, with every sub-account under that login included, and its feature list follows: copy one alert to many accounts, map the symbol (alert on NQ, trade MNQ), set a risk percentage or a multiplier per account. Stocks reach it through Interactive Brokers, TradeStation and Tradier, and the Interactive Brokers route needs TWS or IB Gateway running and logged in somewhere.
A trigger rather than a message. Option Alpha works differently. Its documentation describes a webhook URL that runs up to ten automations in a bot when called, and describes no message fields at all: the automation you built decides the symbol, the structure and the size. That is the one route here that ends in an options spread, which TradersPost cannot place. Tradetron has a signal API in the same spirit — an outside alert fires an entry or exit inside a strategy you built there.
Your own receiver. With ib_async and an Interactive Brokers account, a receiver is a page of Python. This one runs against TWS's paper port, checks a shared secret, refuses a repeat of the same bar and action, and sizes the order itself instead of trusting the chart:
import asyncio
from aiohttp import web
from ib_async import IB, MarketOrder, Stock
SECRET = "YOUR_WEBHOOK_SECRET" # also typed into the alert message
SIZE = {"AAPL": 10} # shares per order, decided here and not on the chart
ib = IB()
seen: set[str] = set()
async def alert(request: web.Request) -> web.Response:
msg = await request.json()
if msg.get("secret") != SECRET:
return web.Response(status=403)
key = f'{msg["ticker"]}|{msg["action"]}|{msg["bar_time"]}'
if key in seen:
return web.Response(text="duplicate ignored")
seen.add(key)
order = MarketOrder(msg["action"].upper(), SIZE[msg["ticker"]], orderRef=key)
ib.placeOrder(Stock(msg["ticker"], "SMART", "USD"), order) # returns at once; no waiting for the fill
return web.Response(text="ok")
async def main() -> None:
await ib.connectAsync("127.0.0.1", 7497, clientId=1) # 7497 is TWS's paper-trading port
app = web.Application()
app.router.add_post("/tradingview", alert)
runner = web.AppRunner(app)
await runner.setup()
await web.TCPSite(runner, "127.0.0.1", 8080).start() # behind an HTTPS proxy on port 443
await asyncio.Event().wait()
asyncio.run(main())
The alert message that goes with it:
{ "secret": "YOUR_WEBHOOK_SECRET", "ticker": "{{ticker}}", "action": "{{strategy.order.action}}", "bar_time": "{{time}}" }
The proxy is not optional: TradingView's help page says it posts only to ports 80 and 443. The
seen set lives in memory and empties on restart — a file or a table is the version you would
leave running.
Where this breaks
Nobody validates the message until it is an order. TradingView's help page says the request
goes out as application/json only if the message is valid JSON after the placeholders are
filled in, and as text/plain otherwise. A trailing comma, a curly quote pasted from a document,
or a placeholder that resolves to something unquoted turns the alert into text, and TradersPost
answers malformed-json or invalid-payload. Use the relay's test webhook, or post the message
to it by hand, before the first live alert.
The alert runs a copy of the script, not the script. The Pine Script manual says that when an alert is created, TradingView saves a mirror image of the script, its inputs, the symbol and the timeframe, and runs that on its servers; later changes to the script or the chart do not reach the alert. Fix a bug in the strategy and the alert keeps trading the old version until you delete it and create it again — and if you create the new one without deleting the old, you now have two.
"Once per bar" fires on a bar that has not finished. Alerts trigger only on real-time bars. A
once-per-bar alert fires the first time the condition is true inside the bar; if the condition is
false by the close, the order exists and the chart, which draws closed bars, shows no signal at
all. Once per bar close waits for the bar to finish. The Pine manual's own advice for avoiding
this kind of repainting is to trigger on the close of the real-time bar, and for strategies it
is the default: unless calc_on_every_tick = true is set, every alert() call in a strategy
fires once per bar close. Check which one each alert uses before it touches money.
Duplicates become orders. A relay passes on what arrives. Two alerts on one condition, one
alert on the indicator and another on the strategy, two charts with the same alert — each is a
separate order, and nothing downstream knows they were one decision. TradersPost's own pages say
signals sent within the same second can race and recommend one to five minutes between signals,
and that failed orders are never retried. The fix is a key: {{ticker}}, the action and
{{time}} identify one bar's decision, and a receiver that refuses the second request with the
same key makes the duplicate harmless. Brokers that take a client order ID give you a second
fence — Alpaca's order endpoint, for one, describes client_order_id as a unique identifier for
the order, up to 128 characters.
Missed alerts send nothing, and nobody tells you. TradingView's help says webhooks may
occasionally fail to reach the URL, and points to the Webhook status column of the alert log. It
also cancels the request if your server takes longer than three seconds to answer, which is why
the receiver above places the order and returns without waiting for a fill. A missed exit is worse
than a missed entry: the strategy on the chart is flat and the account is not. TradersPost's
sentiment of flat exits the full position whatever quantity is sent, and SignalStack's
close, where a broker's page lists it, closes the open one; either makes an exit idempotent in a
way a plain sell 10 is not.
The chart's size is not your account's. {{strategy.order.contracts}} is the size of an
order the strategy tester simulated against the strategy's own starting capital and order-size
setting. Nothing in it knows your buying power, your other positions or your broker's lot size,
and TradersPost does not track margin — an order beyond buying power is simply rejected. Size in
one place, deliberately: the relay's subscription settings, PickMyTrade's per-account risk or
multiplier, or your own receiver, as above.
Seconds, sometimes a minute. TradersPost's FAQ says TradingView webhooks arrive anywhere from
two or three seconds to more than 60 seconds after the condition, and that TradingView considers
25 to 45 seconds normal. PickMyTrade's under-200-millisecond figure is its own side only. A market
order on arrival fills at a price the chart never showed; send {{close}} in the message and
compare it with the fill for a month before you believe a short-timeframe backtest.
Alerts expire. TradingView's help says open-ended alerts are available on Premium and Ultimate only; on the cheaper plans an alert carries an expiry date, and when it passes the alert stops sending. No relay notices an alert that never fires.
The URL is a credential. Anyone who has a relay's webhook URL can post to it. TradingView publishes the four IP addresses its webhooks come from, which a receiver of your own can allowlist; a secret inside the message, as above, is the other half. Do not paste either into a public script or a screenshot.
Paper first, and paper that means something. SignalStack never meters paper orders, so the whole chain can run there for weeks. TradersPost's built-in paper broker fills limit orders at any price and ignores market hours, so it proves the wiring, not the fills — connect a broker's own paper account to see those. Compare the chart's list of trades with the account's order history line by line; every difference is one of the problems above.
If you outgrow this
If the trade is an options spread, a relay that sends one order per alert is the wrong tool: TradersPost places calls or puts in place of shares and nothing multi-leg, and Option Alpha builds and manages the spread inside the bot instead.
If you want the rule and the execution in one product, a builder that runs the strategy itself removes the webhook altogether — Composer for stock and ETF rules through its own brokerage, or a platform such as NinjaTrader where the futures strategy runs inside the software that executes it.
If several accounts follow one alert, the pricing units diverge fast — per account, per order, per login — and TradersPost vs SignalStack does the arithmetic. The rest of the shelf is no-code strategy builders.
The tools that do this
In the order this page recommends trying them. Paid placement does not affect this order.
TradersPost
Reads ticker and action, and takes {{strategy.market_position}} as sentiment. Priced per connected account from $49; 60 webhook calls a minute.
Turns TradingView and TrendSpider alerts into orders at your own broker, per account.
$10/mo
SignalStack
Reads symbol, action and quantity. Five live orders a month free, paper orders never metered, and a test webhook before anything goes live.
Webhook-to-broker order routing, billed per order sent rather than per account.
$27/moFree tier
PickMyTrade
Futures and prop-firm accounts first. One alert copied to every sub-account under a login, size set per account. $50 a month per broker login.
TradingView alerts to futures, prop-firm and IBKR accounts, for one flat fee per login.
$50/mo
Option Alpha
The URL is the trigger and the bot decides the trade, so the order can be an options spread. No message fields to get wrong. $149 a month.
No-code bots for defined-risk options spreads, run in the cloud through your own broker.
$149/mo
ib_async
Your own receiver in Python, ordering through Interactive Brokers' TWS. Free, and every check a relay does is yours to write.
The community continuation of ib_insync — same API, new maintainers, TWS still required.
FreeFree tierOpen source
FAQ
Do TradingView webhook alerts work on the free plan?
No. On TradingView's pricing page, read on 8 October 2026, the Webhook notifications row is unticked for Basic and ticked for Essential, Plus, Premium and Ultimate. The help page adds a second gate that catches people on a paid plan too — webhook alerts are only allowed when two-factor authentication is enabled on the account.
Why did one alert send two orders?
Usually because two alerts exist for one condition — an old alert left running after a new one was created, or one alert on the indicator and another on the strategy. TradingView keeps a frozen copy of the script for each alert, so editing the script does not replace an alert; it adds a reason to create another. A relay passes on whatever arrives. Put the bar time and the action in the message and refuse a second order with the same pair.
Why was the order size different from the strategy tester?
Because the tester's size is computed against the strategy's own simulated capital, not your account. The placeholder {{strategy.order.contracts}} sends the number of contracts the strategy's simulated order filled, which knows nothing of your buying power. Size in the relay's settings or in your own receiver, and leave the chart's number out of the message unless you sized the strategy for that account on purpose.
Can TradingView place the order at my broker without a relay?
Not automatically. With a broker connected, TradingView's order panel is manual order entry. A strategy can fire an alert and the alert can POST to a URL, but something outside TradingView has to receive that request and place the order — a relay service or a receiver of your own.
Sources
- About webhooks — TradingView Help Center — TradingView, read
- How to use a variable value in alert — TradingView Help Center — TradingView, read
- Plans and pricing — TradingView, read
- I upgraded to the Premium plan but my alerts still expiring in 2 months — TradingView Help Center — TradingView, read
- Alerts — Pine Script User Manual — TradingView, read
- Signal Message Reference — TradersPost, read
- TradingView Alerts — SignalStack Help — SignalStack, read
- Webhooks — Option Alpha Docs — Option Alpha, read
- Create an Order — Trading API reference — Alpaca, read
The catalogue next door
This page names a handful of cards. The rest of them are in No-Code Strategy Builders & Auto-Trading, each filled in against the same schema, with the fields to narrow it yourself.
Last updated . Corrected in place: this is a reference page, not a dated post.