TradingView Alerts to MetaTrader 5 with Webhooks — Architecture and Pitfalls
TradingView cannot place MetaTrader orders by itself. A small web service in between can. This guide covers how the pieces fit together and what to get right before real money is involved.
A TradingView-to-MetaTrader bridge has three parts: a TradingView alert that sends a JSON webhook, an HTTPS server (for example FastAPI) that authenticates and validates it, and a MetaTrader 5 side that places the order, either a Python script using the MetaTrader5 package or an Expert Advisor that polls the server. The hard parts are security, duplicate alerts, latency and risk checks, not the happy path.
How the pieces fit together
- TradingView: an indicator or strategy fires an alert; the alert’s webhook URL receives a JSON message. Webhooks require a paid TradingView plan.
- Your server: a public HTTPS endpoint that checks a shared secret, validates the message and records it. TradingView only calls ports 80 and 443 and expects a fast response, so do the heavy work asynchronously.
- MetaTrader 5: either a Python process using the
MetaTrader5package (Windows, with the terminal running) or an Expert Advisor that polls your server withWebRequest, after you allow the URL in the terminal options. The order and risk logic live here.
The alert message
Set the alert message to JSON using TradingView’s placeholders. Because TradingView webhooks cannot add custom headers, put an authentication secret inside the message itself.
{
"secret": "YOUR_LONG_RANDOM_SECRET",
"symbol": "{{ticker}}",
"action": "{{strategy.order.action}}",
"price": {{close}},
"bar_time": "{{time}}"
}
A minimal, secure endpoint
This example authenticates the secret, restricts symbols and actions to an allow-list and drops duplicates. It is a skeleton to show the structure, not a complete trading system.
from fastapi import FastAPI, Request, HTTPException
import hmac, os
app = FastAPI()
SECRET = os.environ["WEBHOOK_SECRET"]
ALLOWED_SYMBOLS = {"XAUUSD", "EURUSD"}
seen = set() # use a database or Redis in production
@app.post("/tv-webhook")
async def tv_webhook(req: Request):
data = await req.json()
# TradingView cannot send custom headers, so the secret travels in the body
if not hmac.compare_digest(str(data.get("secret", "")), SECRET):
raise HTTPException(status_code=403)
if data.get("symbol") not in ALLOWED_SYMBOLS or data.get("action") not in {"buy", "sell"}:
raise HTTPException(status_code=422)
key = (data["symbol"], data["action"], data.get("bar_time"))
if key in seen: # TradingView can send an alert twice
return {"status": "duplicate"}
seen.add(key)
# queue the order for the MetaTrader side (risk checks happen there)
return {"status": "queued"}
Pitfalls that cause bad trades
- Alerts firing on the live bar. A strategy alert evaluated on every tick can fire and then disappear. Use once-per-bar-close alert frequency unless the strategy genuinely needs intrabar signals.
- Duplicates and retries. Make processing idempotent: the same bar and action must never open two trades.
- Symbol mismatch. TradingView and your broker name symbols differently (for example a suffix on the broker side). Keep an explicit mapping table.
- Latency and slippage. The chain adds delay compared with an EA running inside the terminal. Test with small sizes and measure the gap.
- Security. Use HTTPS, a long random secret, an allow-list of symbols and actions, rate limiting and, where your setup allows it, an IP allow-list taken from TradingView’s documentation.
- Risk on the MetaTrader side. Enforce position size, maximum open trades and daily-loss limits there, never trust the alert for sizing.
When a bridge is the wrong tool
If the strategy can be expressed in MQL5, an Expert Advisor running inside the terminal is faster, has no web dependency and is easier to backtest in the Strategy Tester. A bridge makes sense when the logic is already in PineScript, needs TradingView’s data or tools, or must be controlled from several platforms. In the middle ground, converting the PineScript to MQL is often the most robust option; see our conversion service.
Automated trading carries a high risk of loss. Test on a demo account and with small sizes first.
Frequently Asked Questions
Can TradingView place orders in MetaTrader directly?
No. TradingView sends alerts, and a webhook receiver plus a MetaTrader-side component, a Python script or an Expert Advisor, has to turn them into orders.
How do I secure a TradingView webhook?
Use HTTPS, put a long random secret inside the alert message, restrict symbols and actions to an allow-list, rate-limit the endpoint and make processing idempotent so a duplicate alert cannot open a second trade.
Is a webhook bridge better than an Expert Advisor?
Not usually. If a strategy can be written in MQL5, an EA inside the terminal is faster, has no web dependency and is easier to backtest. A bridge makes sense when the logic already lives in PineScript or needs TradingView's data.
Want a TradingView–MetaTrader Bridge Built Securely?
Describe your alerts and broker on Telegram or use the contact form. The initial consultation is free.