TradingView to IBKR: Webhook Bridges vs Your Own Receiver
TradingView cannot send orders to Interactive Brokers (IBKR) automatically: IBKR states that Pine Script is not supported for trading with Interactive Brokers, and TradingView's broker connection is for orders you place yourself. Every automated route therefore runs through a webhook alert, received either by a hosted bridge such as TradersPost, SignalStack or PickMyTrade, or by your own receiver that places orders through an IBKR API. As of November 2026, a bridge is the faster start for simple stock signals. Your own receiver fits better when you need futures roll logic, position reconciliation and risk checks under your control. Below is a tested Python receiver that checks and queues alerts without placing orders.
Can TradingView auto-trade with IBKR? Only through a webhook
IBKR's TradingView FAQ is explicit: Pine Script is not supported for trading with Interactive Brokers. TradingView's help adds that strategy trading is limited to backtesting and that automated strategy trading with a brokerage account is not available yet. The IBKR connection in TradingView's trading panel is for orders you place yourself.
TradingView can send your alert message as an HTTP POST to a URL whenever an alert fires. A hosted bridge or your own receiver at that URL turns the message into an IBKR order. Webhook rules per TradingView, November 2026:
- not available on the free Basic plan, and two-factor authentication must be enabled;
- ports 80 and 443 only, no IPv6, and three seconds for the receiving server to respond;
- valid JSON arrives as
application/json, sent from four published IP addresses; - the help page documents no option for custom headers, such as an
Authorizationheader; - delivery can occasionally fail; the alert log shows each attempt under “Webhook status”.
Four alert details matter. Strategy alerts fire only for orders the broker emulator fills in real time. An alert stops after more than 15 triggers in 3 minutes. It runs on a saved copy of the script and its inputs, so editing the strategy on the chart does not change it. And on Essential and Plus, alerts expire after two months, while Premium and higher offer alerts without expiry. At the receiver, an expired alert looks like silence, not an error.
If you want such a receiver built or an existing bridge reviewed, see TradingView-to-IBKR automation on the trading bot development page.
TradersPost vs SignalStack vs PickMyTrade: how each connects to IBKR
Bridge services give you a webhook URL, define a message format and place the order. The key difference is the IBKR connection behind them. IBKR's list of third-party trading integrations shows TradersPost and SignalStack with a Web API connection (IBKR notes the list may be incomplete and is no endorsement). PickMyTrade documents a route through the TWS API to a TWS or IB Gateway session.
| Route | IBKR connection | Where the IBKR session runs | Instruments (provider docs) | Points to check |
|---|---|---|---|---|
| TradersPost | Web API | at the provider, tied to one IBKR username | stocks only, long and short; labeled beta | one order at a time per account; no API orders for IBKR Lite; only today's orders visible; nightly API reset window from 23:45 to 00:45 ET; keep signals out of it |
| SignalStack | Client Portal (Web) API, authorized via IBKR login | at the provider | not specified on its IBKR connection page | live account and market data subscription required, paper login possible; Lite accounts not eligible; a login elsewhere with the same username drops the session |
| PickMyTrade | TWS API | your TWS or IB Gateway, on your computer, a VPS or a provider-hosted option | stocks, ETFs, options and futures | TWS or IB Gateway must stay running and logged in; on your own machine or VPS, restarts and the weekly login are your job, so check how the cloud option handles them |
| Your own receiver | TWS API via IB Gateway, or Web API via the Client Portal Gateway | your server | what the IBKR API offers for your trading permissions | mapping, checks, logging and monitoring are your code |
Status: provider documentation as of November 3, 2026; coverage and limits change.
The consequence: a Web API bridge spares you a gateway but ties you to the provider's session handling and asset coverage. A TWS API bridge can cover more instruments, but unless the provider hosts the gateway, keeping IB Gateway running and logged in is your work. A self-built Web API route still needs a session: IBKR routes retail Web API authentication through the Client Portal Gateway, a small Java program on your machine (see IBKR Web API vs TWS API).
Your own TradingView webhook receiver: what it has to handle
A self-hosted bridge has three parts: a reverse proxy on port 443 for TLS and the IP allowlist, a receiver that validates and queues each alert and answers at once, and a worker that places orders through the TWS API, typically in Python with ib_async or IBKR's official client. IBKR describes TWS and IB Gateway as a server that API clients connect to after the user has logged in. The API socket has no login of its own, so run IB Gateway on the same machine and accept API connections from localhost only.
Typical example of a strategy alert message (field names are free, the placeholders are TradingView's):
{
"token": "long-random-value",
"symbol": "{{ticker}}",
"exchange": "{{exchange}}",
"target": "{{strategy.market_position}}",
"target_size": "{{strategy.market_position_size}}",
"order_id": "{{strategy.order.id}}",
"bar_time": "{{time}}",
"sent_at": "{{timenow}}"
}Without a documented way to set headers, the token sits in the body. It authorizes signal submission only and is never an IBKR or TradingView password; TradingView advises against login credentials in the message. The core logic:
- Authentication: allowlist TradingView's four source IP addresses at the proxy, compare the token in constant time, reject everything else.
- Idempotency: derive a key from symbol, order ID and bar time, so a duplicate message does not create a second order.
- Target position: read the actual IBKR position and open orders and order only the difference, so reversals and duplicates do not double the position.
- Staleness: drop alerts older than a fixed limit. IBKR's setting “Maintain and resubmit orders when connection is restored”, enabled by default, submits orders received during a connection loss once the connection returns, possibly long after the signal.
- Symbol mapping:
{{ticker}}is a TradingView symbol, not an IBKR contract. Keep a fixed table from TradingView symbol to IBKR contract ID (conId) and reject unknown symbols. - Futures: IBKR's continuous futures type (CONTFUT) serves historical data only, not orders or live data, so a chart like ES1! needs a contract month from your own roll calendar.
- Limits: maximum quantity per symbol (the position size calculator derives it from your risk per trade), trading hours, a daily loss stop and a kill switch.
- Feedback: log every order status, error and execution, and push rejects to a channel someone reads.
TradingView webhook receiver in Python: a tested minimal example
The receiver below uses only the Python standard library. It reads the message from the template above, compares the token in constant time, rejects unknown symbols and alerts older than 60 seconds, and stores each signal once under its idempotency key. A SQLite table serves as the queue. The receiver never connects to IBKR and never places an order: a separate worker reads rows with state new, reconciles them with the actual IBKR position and applies the limits. The handler makes no network calls, so its reply does not wait on IBKR and stays well inside TradingView's three seconds.
"""TradingView webhook receiver: check, deduplicate, queue. Places no orders.
Python 3.9+, standard library only. Listens on 127.0.0.1:8080 behind a proxy."""
import hashlib, hmac, json, os, sqlite3, time
from datetime import datetime, timezone
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
TOKEN = os.environ["WEBHOOK_TOKEN"].encode() # random value, not a password
DB = os.environ.get("QUEUE_DB", "signals.db")
SYMBOLS = {"AAPL", "MSFT"} # explicit allowlist
TARGETS = ("long", "flat", "short") # {{strategy.market_position}}
KEY_FIELDS = ("symbol", "order_id", "bar_time")
MAX_BODY, MAX_AGE = 4096, 60 # bytes, seconds
SCHEMA = ("CREATE TABLE IF NOT EXISTS signals (key TEXT PRIMARY KEY,"
" received REAL, payload TEXT, state TEXT DEFAULT 'new')")
if len(TOKEN) < 32:
raise SystemExit("WEBHOOK_TOKEN needs at least 32 characters")
def enqueue(key, payload):
"""Insert once per key. The table is the queue a separate worker reads."""
db = sqlite3.connect(DB, timeout=1)
try:
with db: # commit or roll back
cur = db.execute(
"INSERT OR IGNORE INTO signals (key, received, payload)"
" VALUES (?, ?, ?)", (key, time.time(), payload))
return cur.rowcount == 1
finally:
db.close()
class Handler(BaseHTTPRequestHandler):
timeout = 2 # drop slow or idle clients
def reply(self, code, text):
body = json.dumps({"result": text}).encode()
self.send_response(code)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
def do_POST(self):
if self.path != "/tv-webhook":
return self.reply(404, "not found")
try:
size = int(self.headers["Content-Length"])
if not 0 < size <= MAX_BODY:
return self.reply(413, "body size")
msg = json.loads(self.rfile.read(size))
token = msg["token"].encode()
except (AttributeError, KeyError, TypeError, ValueError):
return self.reply(400, "bad request")
if not hmac.compare_digest(token, TOKEN): # constant-time check
return self.reply(401, "bad token")
try:
symbol = str(msg["symbol"])
sent = datetime.strptime(msg["sent_at"], "%Y-%m-%dT%H:%M:%SZ")
age = time.time() - sent.replace(tzinfo=timezone.utc).timestamp()
key_src = "|".join(str(msg[k]) for k in KEY_FIELDS)
except (KeyError, TypeError, ValueError):
return self.reply(400, "bad fields")
if symbol not in SYMBOLS or msg.get("target") not in TARGETS:
return self.reply(422, "unknown symbol or target")
if not -5 <= age <= MAX_AGE:
return self.reply(422, "stale alert")
del msg["token"] # never store the secret
key = hashlib.sha256(key_src.encode()).hexdigest()
try:
new = enqueue(key, json.dumps(msg))
except sqlite3.Error:
return self.reply(503, "queue unavailable")
if new:
return self.reply(202, "queued")
return self.reply(200, "duplicate")
class Server(ThreadingHTTPServer):
request_queue_size = 64 # backlog for alert bursts
if __name__ == "__main__":
db = sqlite3.connect(DB)
with db:
db.execute(SCHEMA)
db.close()
Server(("127.0.0.1", 8080), Handler).serve_forever()Local test with curl, in one bash or zsh session:
export WEBHOOK_TOKEN=$(python3 -c "import secrets; print(secrets.token_urlsafe(32))")
export QUEUE_DB="$(mktemp -d)/signals.db" # throwaway queue, never a live one
python3 tv_receiver.py & PID=$! # listens on 127.0.0.1:8080 only
sleep 1
alert() { # $1 = token, $2 = symbol
printf '{"token":"%s","symbol":"%s","target":"long","order_id":"Long",' "$1" "$2"
printf '"bar_time":"2026-11-03T14:30:00Z","sent_at":"%s"}' "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
}
post() {
curl -s -w ' HTTP %{http_code}\n' -H 'Content-Type: application/json' \
-d "$(alert "$1" "$2")" http://127.0.0.1:8080/tv-webhook
}
post "$WEBHOOK_TOKEN" AAPL # {"result": "queued"} HTTP 202
post "$WEBHOOK_TOKEN" AAPL # {"result": "duplicate"} HTTP 200
post wrong-token AAPL # {"result": "bad token"} HTTP 401
post "$WEBHOOK_TOKEN" XYZ # {"result": "unknown symbol or target"} HTTP 422
kill "$PID"Test conditions: run on November 3, 2026 with Python 3.9 and curl 8.7 on macOS, on 127.0.0.1 only, without TradingView, without a broker connection and without orders. Besides the four calls above, the test covered a missing and an oversized body, invalid JSON, a stale sent_at, ten identical alerts sent at the same moment (exactly one queued, nine duplicates; with Python's default listen backlog of five, some connections were reset, hence the larger backlog) and a restart (the duplicate stayed a duplicate). The staleness check compares {{timenow}} with the server clock, so keep that clock synchronized.
Python's documentation says http.server is not recommended for production and only implements basic security checks. Keep the receiver bound to 127.0.0.1 behind the reverse proxy, which terminates TLS and enforces the IP allowlist, or move the same checks into a production web framework. Real alerts need a public HTTPS address on port 443, because TradingView's servers cannot reach 127.0.0.1 on your machine.
IB Gateway for TradingView webhooks: daily resets and the weekly login
IBKR requires a manual login in the TWS or IB Gateway login window and, for security reasons, does not support headless sessions. With “Auto restart”, the application restarts daily without user intervention, but after the server reset on Saturday night IBKR requires the login credentials again. The open-source login helper IBC was retired on September 1, 2026 and archived. Alternatives and their limits: running IB Gateway headless in Docker after IBC.
| IBKR region | Daily reset (Sunday to Friday) | Saturday maintenance |
|---|---|---|
| North America | 00:15 to 01:45 ET | 00:00 to 02:00 ET |
| Europe | 06:25 to 07:45 CET | 00:00 to 02:00 ET |
Source: IBKR system status, retrieved November 3, 2026. During resets, login and order management may be interrupted; existing orders of native types keep working, while execution reports and IBKR-simulated orders are delayed. Signals arriving in a window should expire, not pile up.
One IBKR username can be logged in to only one trading application at a time. The bot therefore needs its own username, separate from TWS, mobile or the TradingView panel.
Bridge service or own receiver: a decision table
| Situation | Hosted bridge | Own receiver |
|---|---|---|
| Stock signals, few symbols, no developer | usually the faster start | more effort than needed |
| Futures with roll dates | not with TradersPost per its docs; elsewhere check contract-month mapping | full control via conId and roll calendar |
| Reconciliation and custom risk limits | limited to provider features | defined by you |
| Who sits in the order path | the provider, with an authorized session or relay | only your server and IBKR |
| Ongoing work | subscription, provider changes and outages | server, updates, weekly login, monitoring |
Cost logic without price tags: a bridge is a subscription on top of a paid TradingView plan. Your own receiver is a one-time build plus server, maintenance and the weekly login. A middle path keeps the bridge and adds a small independent monitor that compares the IBKR position with the expected one every few minutes. It runs under its own IBKR username, so it does not take over the bridge's session, and it catches silent failures such as an expired alert or a dropped session.
Risks and limits of any TradingView-to-IBKR bridge
A bridge executes the strategy's rules faster, mistakes included; it does not make them better.
- Missed alerts: TradingView states that deliveries can fail; a missing exit leaves a position open.
- Data mismatch: signals come from TradingView data and emulated fills, executions from IBKR prices, sessions and contract months.
- State drift: the chart strategy knows nothing about rejects, partial fills or manual trades; only reconciliation against the IBKR position keeps both in line.
- Account access: a hosted bridge holds an authorized session for your account; use a dedicated username with only the permissions it needs.
- Leverage: with futures, short options and other margin positions, losses can exceed the deposit; trading can lead to total loss.
- Paper versus live: a paper account tests the plumbing, not live execution quality.
TradingView to IBKR test checklist before going live
Checklist as of November 2026, for any route; run it in the IBKR paper account first:
- Trigger every signal type once, including exit and reversal, and compare the IBKR position with the strategy's.
- Send the same alert twice; exactly one order may result.
- Send a wrong token, an unknown symbol, a stale alert and an oversized quantity; each must be rejected and reported.
- Stop IB Gateway, or log in elsewhere with the bot's username, while a position is open; verify recovery and reconciliation.
- Run through one daily reset and one weekly login with alerts arriving.
- For futures, play through a roll date and check the contract month in the order.
- Note the expiry date of every alert and set a reminder.
- Go live with small size only after all points pass; the decision to go live stays with the account holder.
If the worker code was written with Claude Code or ChatGPT, add the pre-live checklist for AI-built trading bots.
Frequently asked questions
Can TradingView automatically trade with Interactive Brokers?
Not on its own. IBKR states that Pine Script is not supported for trading with Interactive Brokers, and TradingView says automated strategy trading with a brokerage account is not available yet. Automation needs a webhook alert plus a bridge service or your own receiver that places orders through an IBKR API. Status: November 2026.
Does TradersPost support Interactive Brokers futures?
Not according to its documentation retrieved in November 2026: the TradersPost connection to IBKR runs over the Web API, supports stocks only, long and short, and is still labeled beta. For IBKR futures, look at a bridge whose documentation lists them, typically relaying to your TWS or IB Gateway, or at your own receiver.
What is the difference between PickMyTrade and TradersPost for IBKR?
The connection. TradersPost keeps a Web API login session for your IBKR username on its side. PickMyTrade relays orders through the TWS API to a TWS or IB Gateway session that must be running and logged in, on your own machine, a VPS or its cloud connection. The first spares you a gateway. The second lists more instruments, including futures and options, but on your own machine it leaves gateway operation and the weekly login with you.
Does IB Gateway have to run for TradingView webhooks to IBKR?
Only on TWS API routes: a self-hosted receiver built on the TWS API, or bridges such as PickMyTrade. There, IB Gateway or TWS can restart daily with Auto restart but needs a manual login again after IBKR's Saturday night server reset. Web API bridges such as TradersPost and SignalStack hold a session on their side instead, and a self-built Web API route needs the Client Portal Gateway.
Which TradingView plan do you need for webhook alerts?
Webhook notifications are not included in the free Basic plan; according to TradingView's plan comparison in November 2026, all paid plans include them. On Essential and Plus, alerts expire after two months; Premium and higher offer alerts that do not expire. Two-factor authentication must be enabled on the TradingView account.
How do you secure a TradingView webhook without custom headers?
TradingView's help documents no way to add an Authorization header, so put a long random token in the JSON body and compare it in constant time. Serve the receiver over HTTPS on port 443 and allowlist the four source IP addresses TradingView publishes. The token authorizes nothing but signal submission; never put an IBKR or TradingView password in the alert. Keep the IB Gateway API port reachable from localhost only.
How can you test a TradingView webhook receiver locally?
Run the receiver on 127.0.0.1 and send the alert JSON with curl: a valid alert, the same alert again, a wrong token and an unknown symbol, then check each status code and the queue. TradingView cannot reach localhost, so real alerts need a public HTTPS address on port 443. After that, run the whole chain with real TradingView alerts against an IBKR paper account before any live order.
Sources and status
- TradingView Frequently Asked Questions (Pine Script and IBKR) — Interactive Brokers (retrieved November 3, 2026)
- How to autotrade using Pine Script strategies — TradingView (retrieved November 3, 2026)
- How to configure webhook alerts — TradingView (retrieved November 3, 2026)
- Strategy Alerts — TradingView (retrieved November 3, 2026)
- Pine Script User Manual: Alerts — TradingView (retrieved November 3, 2026)
- Plans and pricing: feature comparison (webhook notifications, alert durations) — TradingView (retrieved November 3, 2026)
- Available Integrations (third-party trading software) — Interactive Brokers (retrieved November 3, 2026)
- Interactive Brokers connection guide — TradersPost (retrieved November 3, 2026)
- Connect Interactive Brokers — SignalStack (retrieved November 3, 2026)
- TradingView to Interactive Brokers (IBKR and TWS) — PickMyTrade (retrieved November 3, 2026)
- TWS API: Download TWS or IB Gateway (manual login, auto restart) — Interactive Brokers (retrieved November 3, 2026)
- TWS API: Logging into multiple applications — Interactive Brokers (retrieved November 3, 2026)
- TWS API: Intelligent Order Resubmission — Interactive Brokers (retrieved November 3, 2026)
- TWS API: Futures contracts (Continuous Futures) — Interactive Brokers (retrieved November 3, 2026)
- Web API: Getting Started (retail access via Client Portal Gateway) — Interactive Brokers (retrieved November 3, 2026)
- http.server: HTTP servers (security note) — Python Software Foundation (retrieved November 3, 2026)
- socketserver: request_queue_size (listen backlog, default 5) — Python Software Foundation (retrieved November 3, 2026)
- Current System Status: daily reset schedule — Interactive Brokers (retrieved November 3, 2026)
- IBC repository (retirement notice) — IbcAlpha on GitHub (retrieved November 3, 2026)
As of November 2026. Third-party rules, prices and APIs may have changed since; the providers' current documentation and the official texts are authoritative.
Need a TradingView-to-IBKR bridge built or reviewed? Get in touch — a free intro call covers symbol mapping, risk checks, IB Gateway operation and the test plan for the paper account. More: Trading bot development for Interactive Brokers and MetaTrader 5.