Short answer: TradingView to MT5 has no direct order link: TradingView's Help Center, read 5 November 2026, says automated strategy trading with a brokerage account is not available, and MQL5's network functions only make outbound connections. So the terminal cannot be the webhook URL; people use a public receiver, a queue, and an Expert Advisor or the MetaTrader5 Python package beside the terminal to collect orders. TradingView's Terms of Use, section 3, prohibit using alerts and webhooks for automated trading, so read them first.
Work out lots, units and pip values with your own figures: Forex position size calculator and Pip calculator.
TradingView's Terms of Use (opens in a new tab), read on 5 November 2026, license alerts and webhooks for display use and prohibit using them for automated trading, including through third-party products or services. Read those terms and take legal advice before relying on this route.
The queue below ran with synthetic alerts on 5 November 2026; MetaEditor and a terminal are not available here, so the MQL5 code was not compiled or run. Leveraged forex carries high risk, and automated orders can lose money quickly. Rules depend on your country, account types and API access vary by broker, and no broker is recommended, ranked or linked with a referral here.
Can you connect TradingView to MT5 directly?
Not for automated orders: none of the TradingView Help Center pages read on 5 November 2026 describes an order route to an MT5 account.
- Strategies. Strategy trading is limited to backtesting; automated strategy trading with a brokerage account is not available yet.
- Signing in is not trading. For one broker's MT4 and MT5 accounts, you can log in, but trading is not available.
- Alerts. TradingView says they are not designed for automated trading.
| TradingView | MT5 | What follows |
|---|---|---|
| Posts only to ports 80 and 443; no IPv6 | WebRequest is an outbound call; the 14 Socket* functions connect, read and send, and none binds or accepts | The terminal cannot be the webhook URL; a public receiver must exist |
| Cancels a request after 3 seconds | WebRequest blocks the Expert Advisor until a reply or timeout | The receiver replies at once and the order happens later |
| Resends after HTTP 500 to 599, except 504, up to 3 times, 5 seconds apart | A repeated market order is a second deal | Filter on an ID carried in the alert |
The terminal's built-in MCP server (opens in a new tab), added in build 6060 (23 July 2026), does listen, but on an address such as 127.0.0.1, with a bearer token and for AI clients, so it is not a webhook target. MQL5 has no function that accepts connections, so a listener would need a DLL, and DLL calls are completely forbidden on MetaQuotes' virtual hosting (opens in a new tab).
Do TradingView's terms allow a webhook bridge to MT5?
Not as written: section 3 lists automated trading and automated order generation among prohibited uses of TradingView content, including alerts and webhooks. It also bars any third party from creating, offering or operating a product that relies on them for automated trading, or advertising webhooks for such purposes, which reaches developers and connector sellers. This is a contract matter, separate from financial regulation, and not legal advice.
| Your position | Sensible step |
|---|---|
| You depend on this route for real money | Take legal advice and ask TradingView in writing whether your use is permitted |
| TradingView charts are only where the rules were developed | Run the rules without it: an MQL5 port or Python on data from your broker; see Pine Script to MQL5 |
| You sell or build bridges for others | Read the third-party wording closely, because it is aimed at you |
TradingView to MT5 bridge routes compared
Three routes are documented for programs and a fourth for AI clients.
| Route | How orders arrive | What must run | Weakest point |
|---|---|---|---|
Expert Advisor polling with WebRequest | Asks your queue on a timer, then sends the order | Terminal, the EA, your URL allowed by hand | Each poll blocks the EA; WebRequest does not run in the Strategy Tester, so test on a demo |
| Expert Advisor on a socket | Holds an outbound TCP or TLS connection and reads it on a timer | The same, plus your socket server | You own framing, TLS checks and reconnects |
| Python worker | Reads your queue and calls order_send | Terminal and Python on one Windows machine | No events, so poll for state: see MT5 Python |
| Local MCP client | Calls trade_send_market_order on the terminal's MCP server | Build 6060 or later, MCP enabled, a token | Written for AI clients; not tested here |
If you consider a paid connector, ask which route it uses, where your password lives and what happens when the terminal is closed. The wider picture is in MT5 API.
TradingView webhook to MT5: a queue that fails safely
The queue below hands the terminal one order at a time, at most once per alert, expires alerts the terminal missed, and stops if an order's result is unknown.
Receiver code, payload design and architecture are in TradingView webhook in Python, alert message JSON and TradingView webhook bot; MT5 adds a pull queue and a lot conversion. Put an ID such as {{ticker}}-{{strategy.order.id}}-{{timenow}} in the alert; per the Help Center (opens in a new tab), {{timenow}} is the fire time and {{time}} the bar's time, which two fills in one bar would share.
import sqlite3, threading, time
from decimal import Decimal as D, InvalidOperation
TTL, ACK_WAIT = 30, 15 # seconds; illustrative, your rules decide
def to_lots(units, size, vmin, vmax, step):
try:
units, size, vmin, vmax, step = (D(str(v)) for v in (units, size, vmin, vmax, step))
lots = units / size // step * step # floor to the step, never round up
return lots if vmin <= lots <= vmax else None
except InvalidOperation: # "nan", "1e400", text: refuse, do not crash
return None
class OrderQueue:
def __init__(self, path=":memory:", clock=time.time):
self.db = sqlite3.connect(path, check_same_thread=False, isolation_level=None) # autocommit
self.clock, self.lock = clock, threading.Lock()
self.db.execute("""CREATE TABLE IF NOT EXISTS q (id TEXT PRIMARY KEY, line TEXT,
created REAL, state TEXT DEFAULT 'new', leased REAL, retcode INT)""")
def put(self, alert_id, side, symbol, lots): # a resend repeats the ID: no change
side = str(side).upper() # {{strategy.order.action}} is lowercase
line = f"{alert_id}|{side}|{symbol}|{lots}"
ok = isinstance(lots, D) and lots.is_finite() and lots > 0 and side in ("BUY", "SELL")
if not (ok and alert_id and symbol and line.count("|") == 3):
raise ValueError(line)
with self.lock:
self.db.execute("INSERT OR IGNORE INTO q(id, line, created) VALUES (?, ?, ?)",
(alert_id, line, self.clock()))
def next(self):
with self.lock:
now, sql = self.clock(), self.db.execute
sql("UPDATE q SET state='expired' WHERE state='new' AND created<?", (now - TTL,))
sql("UPDATE q SET state='unknown' WHERE state='leased' AND leased<?", (now - ACK_WAIT,))
if sql("SELECT 1 FROM q WHERE state IN ('leased', 'unknown')").fetchone():
return "" # one order in flight; unknown waits for a person
row = sql("SELECT id, line FROM q WHERE state='new' ORDER BY created LIMIT 1").fetchone()
if row is None:
return ""
sql("UPDATE q SET state='leased', leased=? WHERE id=?", (now, row[0]))
return row[1]
def ack(self, alert_id, retcode):
with self.lock:
self.db.execute("UPDATE q SET state='done', retcode=? WHERE id=? AND state IN ('leased', 'unknown')",
(retcode, alert_id))The receiver in front should check the secret, map the symbol and answer 422 when put raises ValueError, since TradingView resends after a 500. Synthetic alerts, Python 3.11, 5 November 2026:
| Case | Result |
|---|---|
| Same ID twice, side "buy" | One row, stored as BUY |
| Empty ID, side "close", a "|" in the ID, lots None or 0 | ValueError |
| Poll twice before the acknowledgment | a1|BUY|EURUSD.m|0.10, then empty |
| Terminal away for 31 seconds | Expired, never sent |
| No acknowledgment for 16 seconds, then a late one | Marked unknown and polls return empty, so a new alert waits; the late one is recorded and the line resumes |
| Eight threads poll at once, 300 trials; file reopened | Each alert sent once; rows kept |
Without the lock, most of 300 trials sent an alert more than once; without isolation_level=None, the reopened file was empty. If the terminal sent an order and crashed before reporting it, redelivery could double the position, so a person compares the terminal's history with the queue first.
The Expert Advisor that collects orders (not compiled)
This Expert Advisor polls once a second, sends one order per line through CTrade and reports the return code and deal ticket back.
// NOT COMPILED OR RUN: MetaEditor is not available here.
#include <Trade\Trade.mqh>
input string InpBase = "https://bridge.example.com";
input string InpToken = ""; // queue token, never an account password
input long InpMagic = 240001; // your own number
CTrade trade;
int OnInit()
{
trade.SetExpertMagicNumber(InpMagic);
return(EventSetTimer(1) ? INIT_SUCCEEDED : INIT_FAILED);
}
void OnTimer()
{
char none[], reply[], body[];
string got, head = "X-Token: " + InpToken + "\r\n", f[];
int code = WebRequest("GET", InpBase + "/next", head, 3000, none, reply, got);
if(code == 200 && StringSplit(CharArrayToString(reply), '|', f) == 4) // id|side|symbol|lots
{
uint rc = 0; // stays 0 if the symbol or side is unknown
ulong deal = 0;
if(SymbolSelect(f[2], true) && (f[1] == "BUY" || f[1] == "SELL"))
{
trade.SetTypeFillingBySymbol(f[2]);
if(f[1] == "BUY")
trade.Buy(StringToDouble(f[3]), f[2]);
else
trade.Sell(StringToDouble(f[3]), f[2]);
rc = trade.ResultRetcode();
deal = trade.ResultDeal();
}
string ack = f[0] + "|" + (string)rc + "|" + (string)deal;
StringToCharArray(ack, body, 0, StringLen(ack));
WebRequest("POST", InpBase + "/ack", head, 3000, body, reply, got);
}
else if(code == -1 || code > 200)
Print("Poll failed: HTTP ", code, ", error ", GetLastError());
}- Allowed URL. Per the reference (opens in a new tab), an address cannot be added programmatically: add it in the Expert Advisors tab of Options.
- Timer. A new Timer event is not queued while one waits or runs, per EventSetTimer (opens in a new tab), so a slow request skips polls rather than stacking them.
- Success.
Buyreturning true does not mean execution, per the reference (opens in a new tab), so the code reportsResultRetcode(). - Not included. Closing logic, limits and reconciliation.
TradingView alert to MT5: symbols, lots and position modes
The bridge must translate symbol, size and position logic before an order exists.
| Item | In the alert | In MT5 | Translate how |
|---|---|---|---|
| Symbol | {{ticker}} | Broker's name, perhaps with a suffix | An explicit map; refuse the unknown |
| Size | {{strategy.order.contracts}} | Lots, with broker-set contract size, minimum, maximum and step | Convert, floor to the step, reject out of range |
| Position | strategy.entry() reverses (opens in a new tab) by adding the position's size | Netting: one position per symbol. Hedging: an opposite deal opens another | Read ACCOUNT_MARGIN_MODE; on hedging, close by ticket |
Hypothetical example: contract size 100,000, step 0.01, minimum 0.01, maximum 500. An alert for 29,000 units is 0.29 lots, but 29000 / 100000 / 0.01 gave 28.999999999999996 in Python, so int() yields 0.28 lots. The to_lots function above returned 0.29 with float or string broker values, and None for 499 units, 60,000,000 units, "1e400" and "nan".
The broker sets netting or hedging per account, per MetaTrader 5's help. PositionClose by symbol on a hedging account closes the lowest ticket, which may not be the one you meant.
What breaks a TradingView to MT5 setup: return codes
Most failures show up as a return code or as silence, so log both and alarm on silence.
| Evidence | Official meaning or cause | Fix |
|---|---|---|
| 10030 | Invalid order filling type; Return is disabled under Market Execution | Set filling from the symbol's flags |
| 10027 | Autotrading disabled by client terminal | Enable it; check TERMINAL_TRADE_ALLOWED at start |
| 10018 | Market is closed | Let the alert expire unless your rules say otherwise |
| Return code 0 in this sample | Unknown symbol (wrong name or missing suffix) or side | Fix the symbol map |
WebRequest returns -1 | For example, a URL missing from the allowed list | Add it; read GetLastError() |
| No polls arriving | Terminal closed or disconnected, EA removed | Alarm on the age of the last poll |
Whose alerts, which account, which country
Use alerts from rules you wrote, on your own account.
- Your own alerts. No third-party signal feeds and no trade copier: ESMA's briefing of 30 March 2023 (opens in a new tab) (paragraph 12) treats a firm's automatic execution of third-party signals, with no action by the client, as portfolio management under MiFID.
- Broker and prop firm terms. They bind you and may restrict automation.
- Your country. For readers in Turkey: the Capital Markets Board (SPK) said on 23 February 2023 (opens in a new tab) that residents may carry out leveraged FX trades only through firms it has authorized (Law No. 6362 Articles 99(4) and 109(2)).
For integration work in general, see TradingView automation; naming MetaTrader 5 here does not mean Fincode integrates it or has built on it.
Frequently asked questions
How do I connect MT5 to TradingView?
There is no direct order link. The route people use is a webhook to their own receiver, a queue, and an Expert Advisor or Python worker beside the terminal; read TradingView's Terms of Use, section 3, and take legal advice first.
Can TradingView send a webhook straight to MT5?
No. TradingView posts only to ports 80 and 443 of a public address, while MQL5's network functions only connect outward, and the terminal's MCP server is for AI clients.
Does this work for TradingView to MT4?
The queue does, and MQL4 also has WebRequest, but MQL4's order functions differ and the MetaTrader5 Python package is documented for MetaTrader 5 only, so the Expert Advisor needs rewriting.
Does the terminal have to stay open?
Yes. Without a logged-in terminal nothing collects from the queue, so alerts should expire and an alarm should fire.
Sources
- TradingView: Terms of Use, section 3 (display-only use, non-display prohibitions) (opens in a new tab)
- TradingView Help Center: How to configure webhook alerts (opens in a new tab)
- TradingView Help Center: How to autotrade using Pine Script strategies (opens in a new tab)
- TradingView Help Center: Webhook resubmission (opens in a new tab)
- TradingView Help Center: Using credentials for webhooks (opens in a new tab)
- TradingView Help Center: I have an MT4/MT5 Forexcom account. Can I trade with it on TradingView? (opens in a new tab)
- MQL5 Reference: WebRequest (opens in a new tab)
- MQL5 Reference: Network functions (Socket list, allowed addresses) (opens in a new tab)
- MQL5 Reference: Trade Server Return Codes (opens in a new tab)
- MQL5 Reference: Order Properties (filling policies) (opens in a new tab)
- MQL5 Reference: CTrade PositionClose (lowest ticket on hedging accounts) (opens in a new tab)
- MetaTrader 5 Help: General principles (netting and hedging, set by the broker) (opens in a new tab)
- ESMA: Supervisory briefing on copy trading, 30 March 2023 (opens in a new tab)
- SPK: Press notice on unauthorized leveraged trading, 23 February 2023 (Turkish) (opens in a new tab)
- Capital Markets Law No. 6362, Articles 99 and 109 (Turkish, consolidated text) (opens in a new tab)
This guide is general information about software and markets, not investment, legal or tax advice. Automated trading can lose money, past or backtested performance does not guarantee future results, and the rules that apply depend on your jurisdiction and your exchange's terms. Sources, checks and corrections: see the editorial policy.