# MT4 API: MQL4, broker-side APIs and Python routes

URL: https://fincodelabs.com/en/blog/mt4-api · Publisher: Fincode (Fincode Yazılım ve Teknoloji A.Ş.), Istanbul, Turkey · Category: Stocks, forex and broker APIs · Published: 2026-11-06 · Updated: 2026-11-06

MT4 API, checked 6 November 2026: no REST API or Python package from MetaQuotes, MQL4 WebRequest as the official way out, and APIs reserved for brokers.

**Short answer:** The **MT4 API** a trader can use is MQL4: on 6 November 2026 no REST trading API or Python package for MetaTrader 4 was found on MetaQuotes' official pages. An MQL4 Expert Advisor trades inside the terminal and can call your own server with `WebRequest`, which is how Python usually connects. The Server, Manager, DataFeed, Report and WebServices APIs are for brokers, and MetaQuotes no longer sells MT4 licenses.

Official pages were read on 6 November 2026. No MetaTrader 4 terminal or broker account was used, so no MQL4 code was compiled and no order was placed; the Python below ran offline on synthetic data.

Leveraged forex and CFD trading 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.

## Is there an official MT4 API?

Not for traders in the REST sense: MetaQuotes documents MQL4 for programs inside the terminal and five broker-side APIs, and no REST or Python interface for traders was found.

**What MT4 API can mean, from official pages read 6 November 2026**

| What | For whom | Where it runs | Public documents |
| --- | --- | --- | --- |
| MQL4 Expert Advisors and scripts | Traders | Inside the terminal | Yes, the MQL4 reference |
| `WebRequest` from an Expert Advisor | Traders | The terminal calls your server | Yes, the MQL4 reference |
| Server, Manager, DataFeed, Report and WebServices APIs | Brokers running MT4 servers | Broker side | Purposes only; details behind a login |
| Third-party bridges and libraries | Anyone | Varies | The vendor's own |

MetaQuotes says it does not provide brokerage services; your account sits on your broker's MT4 server. Its API page also says "The MetaTrader 4 trading platform licenses are no longer available for purchase" and reserves further conceptual updates for MetaTrader 5, though the release notes still list build 1490, dated 2 October 2026. That build changed how Stop Loss and Take Profit levels are shared between positions on one instrument in FIFO mode, so retest a bridge after each build.

## MT4 API documentation: what is public and what is not

The public part is the MQL4 reference at docs.mql4.com; MetaQuotes' MT4 support documentation sat behind a login on 6 November 2026.

Requests to `support.metaquotes.net/en/docs/mt4` and `/en/docs/mt4/api` redirected to a login page, so nothing is said here about those APIs' endpoints or limits. What the reference does document:

**Data in and out, from the MQL4 reference read 6 November 2026**

| Mechanism | What the reference says |
| --- | --- |
| `WebRequest` | Synchronous: the program waits for the reply. Expert Advisors and scripts only; from an indicator it fails with error 4060. Not available in the Strategy Tester |
| Allowed URLs | Each server must be on the allowed list in the Options window, Expert Advisors tab; the port is 80 for http and 443 for https |
| Sockets | None found; the reference notes that MQL5 added TCP network functions that need no third-party DLLs |
| Files | Only inside `MQL4\Files` or the common folder shared by all terminals |

No function for accepting incoming connections was found, so programs outside the terminal wait until it asks.

## MT4 Python: which routes exist?

No official Python package for MT4 was found, so Python reaches it through MQL4 code in the terminal or a third-party product, or the account moves to MT5.

MetaQuotes' own `MetaTrader5` package (5.0.6231, uploaded 27 September 2026, MIT license, Windows wheels only) is summarized on PyPI as "API Connector to MetaTrader 5 Terminal". PyPI returned HTTP 404 for a project named `MetaTrader4` on 6 November 2026.

**Python routes to MT4; no product is named or ranked**

| Route | What can go wrong |
| --- | --- |
| Expert Advisor polls your HTTPS service | Terminal running and logged in, EA on a chart; a slow reply blocks it |
| Expert Advisor and Python share files | Locking, half-written files, cleanup |
| Expert Advisor loads a DLL with sockets or a queue | Outside code runs inside the terminal, and DLL use must be allowed |
| Move the account to MT5 | A rewrite of the MQL4 code; see [MT5 Python](https://fincodelabs.com/en/blog/metatrader-5-python) |

## How an Expert Advisor connects MT4 to Python

The terminal calls out, never in: an Expert Advisor asks your service for work on a timer, places the order itself and reports back.

1. Python checks each command and turns it into a line, `id;symbol;side;lots`, for MQL4's `StringSplit`.
2. The Expert Advisor polls with a timer ([EventSetTimer](https://docs.mql4.com/eventfunctions/eventsettimer)). Each program gets one timer, and no new timer event is queued while one waits or runs, so a slow request delays polling instead of stacking.
3. It checks trading permission in the terminal, the program and the account, which the trade server can disable.
4. It reads lot limits and the stop level with `MarketInfo`, calls `OrderSend` with a magic number and the ID as comment, then posts the ticket or error code back.

The Python half, run offline on 6 November 2026 with Python 3.11; the symbols are synthetic, and the 5-lot cap and 0.01 step are hypothetical.

```python
import re
from decimal import Decimal

SIDES = {"buy": 0, "sell": 1}             # OP_BUY and OP_SELL in MQL4
ID = re.compile(r"[A-Za-z0-9]{8}")        # fixed length; see error 128 below
LOTS = re.compile(r"[0-9]+(\.[0-9]+)?")   # Decimal reads 0_5 as 5

class Rejected(ValueError):
    pass

def resolve(base, listed):              # EURUSD -> EURUSD.r, only if one match
    rule = re.compile(re.escape(base) + r"([._-]\w*|[a-z]*)")
    hits = [s for s in listed if base and rule.fullmatch(s)]
    if len(hits) == 1:
        return hits[0]
    raise Rejected(f"{repr(base)}: {len(hits)} matches {hits}")

def encode(cmd, listed, seen, max_lots=Decimal("5"), step=Decimal("0.01")):
    cid = cmd.get("id")
    if not isinstance(cid, str) or not ID.fullmatch(cid):
        raise Rejected(f"bad id {repr(cid)}")
    if cid in seen:
        raise Rejected(f"duplicate id {cid}")
    side = SIDES.get(str(cmd.get("side", "")).lower())
    if side is None:
        raise Rejected(f"{cid}: bad side {repr(cmd.get('side'))}")
    text = str(cmd.get("lots"))
    if not LOTS.fullmatch(text):
        raise Rejected(f"{cid}: lots {repr(text)} is not a plain decimal")
    lots = Decimal(text)
    if not 0 < lots <= max_lots or lots % step:
        raise Rejected(f"{cid}: lots {repr(text)} out of range or step")
    symbol = resolve(str(cmd.get("symbol") or ""), listed)
    seen.add(cid)
    return f"{cid};{symbol};{side};{lots.quantize(step)}"

listed = ["EURUSD.r", "EURUSDm", "GBPUSD.r", "US300.r", "XAUUSD.r"]   # synthetic
seen = set()
for cid, symbol, side, lots in [
        ("a0000001", "GBPUSD", "buy", "0.10"),
        ("a0000001", "GBPUSD", "buy", "0.10"),
        ("", "GBPUSD", "buy", "0.10"),
        ("a0000002", "EURUSD", "buy", "0.10"),
        ("a0000003", "US30", "buy", "0.10"),
        ("a0000004", "GBPUSD", "buy", "1e400"),
        ("a0000005", "GBPUSD", "buy", "1e-400"),
        ("a0000006", "XAUUSD", "SELL", 1)]:
    cmd = {"id": cid, "symbol": symbol, "side": side, "lots": lots}
    try:
        print("send  ", encode(cmd, listed, seen))
    except Rejected as err:
        print("refuse", err)
```

Output:

```
send   a0000001;GBPUSD.r;0;0.10
refuse duplicate id a0000001
refuse bad id ''
refuse 'EURUSD': 2 matches ['EURUSD.r', 'EURUSDm']
refuse 'US30': 0 matches []
refuse a0000004: lots '1e400' is not a plain decimal
refuse a0000005: lots '1e-400' is not a plain decimal
send   a0000006;XAUUSD.r;1;1.00
```

Each refusal is a common bridge failure: a repeated or empty ID, a symbol that fits two broker names or only a different instrument (`US300.r` is not US30), and lots that parse to infinity or almost zero. A refused ID stays free for a corrected command. The MQL4 side, using the second `WebRequest` form:

```
// not compiled for this guide
void OnTimer()                         // EventSetTimer(2) in OnInit starts it
  {
   char   body[], reply[];
   string replyHeaders;
   string f[];
   ResetLastError();
   int status = WebRequest("GET", "https://bridge.example.com/next",
                           "Authorization: Bearer QUEUE-TOKEN\r\n", 5000,
                           body, reply, replyHeaders);
   if(status == 200 && StringSplit(CharArrayToString(reply), ';', f) == 4)
      Print("command ", f[0]);         // check the ID record, then OrderSend
   else if(status == 200 || status < 0 || status > 299)   // 204 (empty queue): no log
      Print("poll failed: HTTP ", status, ", error ", GetLastError());
  }
```

Serve lines over HTTPS from an allowed URL, check the token before anything else, and never send an account password.

## MT4 OrderSend errors a bridge must handle

Handle a failed `OrderSend` by its code: some failures leave the order's fate unknown, and a blind retry can double it.

**MQL4 error list and OrderSend page, read 6 November 2026**

| Code | Reference text | What the bridge should do |
| --- | --- | --- |
| 128 | Trade timeout | Result unknown: search open orders by magic number and ID before any retry |
| 129, 138 | Invalid price; requote | Refresh prices and decide again |
| 130 | Invalid stops | Normalize levels and respect the stop level; zero can mean it floats |
| 146 | Trade context is busy | Wait, then retry a limited number of times |
| 147, 148 | Expiration denied; too many orders | Broker limits on expiry and order count: report, do not retry unchanged |
| 4109, 4112 | Trade not allowed; automated trading disabled by the trade server | Report it; do not retry |
| 5200 to 5203 | WebRequest errors | A failed poll traded nothing, so keep commands queued until their result arrives; resend failed reports |

> **Hypothetical example.** The Expert Advisor sends a 0.10-lot buy for ID a0000001 and gets error 128. Sending again could open a second position, so it first looks for an open order with its magic number and a comment starting a0000001. Fixed-length IDs keep a1 from matching a10, but the `OrderSend` page says the server may change the last part of the comment, so also check the EA's own record, written before each order.

## MT4 Manager API and the other broker-side APIs

They extend a broker's MT4 servers, not a trader's terminal; MetaQuotes' API page lists five.

**Purposes as stated on MetaTrader 4's API page, read 6 November 2026**

| API | Stated purpose |
| --- | --- |
| Server API | Server plugins, including order and customer management and processing trade requests |
| Manager API | Extra functions, integration and customization, up to your own manager terminal |
| DataFeed API | News and quote data feeds |
| Report API | Custom reports on financial operations and trader accounts |
| WebServices API | Integrating the platform with websites, such as user accounts and quotes |

With licenses no longer sold, the MT4 Manager API lives at brokers that already run MT4, and access goes through them. A broker's own API may also cover accounts used with MT4, with extra rules: OANDA's v20 order definitions say not to set, modify or delete client extensions if your account is associated with MT4 (read 6 November 2026; see the [OANDA API guide](https://fincodelabs.com/en/blog/oanda-api-python)).

## Third-party MT4 bridges: what to check

A bridge adds another party that can trade your account, so judge it on credentials, failure handling and your broker's terms.

- **Passwords.** MT4 help says the investor password lets you see the account and analyze prices but not trade, automated trading included, so a hosted bridge that trades needs the full-rights password. Storage practice is in [API key security](https://fincodelabs.com/en/blog/api-key-security-trading-bots).
- **Meaning.** MT4 bridge can also mean a broker's link to liquidity providers; ask which is on offer.
- **DLLs.** A DLL runs inside the terminal with your user's rights, and the [#import](https://docs.mql4.com/basis/preprosessor/import) page says the compiler cannot verify the parameters passed to it; load only code you can inspect.
- **Terminal-free libraries.** Some claim to reach MT4 servers without a terminal. No public client protocol for that was found on MetaQuotes' pages on 6 November 2026, and how they work could not be checked. Treat them as a risk, never as a way around your broker's terms, and ask your broker in writing first.

Questions for comparing any broker connection are in [REST, WebSocket and FIX](https://fincodelabs.com/en/blog/broker-api-integration-fix-rest).

## MT4 or MT5 for a new API project?

For new work MT5 has documented interfaces that MT4 lacks; MT4 makes sense when the account has to stay on MT4.

**Official interfaces, from MetaQuotes' pages and PyPI read 6 November 2026**

| Interface | MT4 | MT5 |
| --- | --- | --- |
| Python package from MetaQuotes | None found | MetaTrader5 5.0.6231, Windows wheels |
| TCP sockets in the language | None found | Yes, network functions |
| AI clients | None found | Native MCP support since build 6060, 23 July 2026 |
| New broker licenses | No longer available for purchase | Brokers can request access |
| Further conceptual updates | No, per MetaQuotes | Yes, per MetaQuotes |

Moving is a rewrite, as the [MQL5 developer checklist](https://fincodelabs.com/en/blog/mql5-developer) shows, and the [MT5 API guide](https://fincodelabs.com/en/blog/mt5-api) maps the MT5 routes.

For readers in Turkey: the Capital Markets Board (SPK) [said on 23 February 2023](https://spk.gov.tr/duyurular/basin-duyurulari/2023/izinsiz-kaldiracli-islemlere-iliskin-basin-duyurusu) that residents may trade forex with leverage only through firms it has authorized, and the notice was still online on 6 November 2026. Anyone else who has residents trade with leverage commits the crime of unauthorized capital markets activity, carrying two to five years in prison and a judicial fine of 5,000 to 10,000 days, and SPK can order content removed or access blocked where leveraged trades abroad are offered to residents over the internet ([Law No. 6362](https://www.mevzuat.gov.tr/mevzuatmetin/1.5.6362.pdf) Articles 99(4) and 109(2)).

For integration work in general, see [broker API integration](https://fincodelabs.com/en/services/broker-api-integration); naming MetaTrader 4 or OANDA here does not mean Fincode integrates them or has built on them.

## Frequently asked questions

### Does MT4 have a REST API?

No public REST trading API from MetaQuotes was found on 6 November 2026. The WebServices API is broker-side, for integrating the platform with websites.

### Can I use Python with MetaTrader 4?

Not through an official package; MetaQuotes' MetaTrader5 package connects to the MetaTrader 5 terminal. Use an Expert Advisor that calls your Python service, a bridge, or MT5.

### Where is the MT4 API documentation?

The MQL4 reference at docs.mql4.com is public; MetaQuotes' MT4 support documentation redirected to a login page on 6 November 2026.

### Is MetaTrader 4 still updated?

Its release notes list build 1490, dated 2 October 2026, while MetaQuotes reserves further conceptual updates for MetaTrader 5.

## Sources

- [MetaTrader 4 API: Server, Manager, DataFeed, Report and WebServices APIs; licenses no longer available](https://www.metatrader4.com/en/brokers/api)
- [MetaTrader 4 for brokers (MetaQuotes does not provide brokerage services)](https://www.metatrader4.com/en/brokers)
- [MetaTrader 4 release notes (build 1490, 2 October 2026)](https://www.metatrader4.com/en/releasenotes)
- [MQL4 Reference: WebRequest](https://docs.mql4.com/common/webrequest)
- [MQL4 Reference: Common functions, including SendFTP, SendMail, SendNotification and the note on MQL5 network functions](https://docs.mql4.com/common)
- [MQL4 Reference: File functions and the file sandbox](https://docs.mql4.com/files/)
- [MQL4 Reference: OrderSend](https://docs.mql4.com/trading/ordersend)
- [MQL4 Reference: Runtime error codes](https://docs.mql4.com/constants/errorswarnings/errorcodes)
- [MQL4 Reference: Trade permission](https://docs.mql4.com/runtime/tradepermission)
- [MetaTrader 4 Help: Authorization (normal and investor passwords)](https://www.metatrader4.com/en/trading-platform/help/userguide/authorization)
- [PyPI: MetaTrader5 5.0.6231 by MetaQuotes](https://pypi.org/project/MetaTrader5/)
- [MetaTrader 5 release notes (build 6060, MCP support, 23 July 2026)](https://www.metatrader5.com/en/releasenotes)
- [OANDA v20 REST API: Order definitions (client extensions and MT4 accounts)](https://developer.oanda.com/rest-live-v20/order-df/)
- [SPK: Press notice on unauthorized leveraged trading, 23 February 2023 (Turkish)](https://spk.gov.tr/duyurular/basin-duyurulari/2023/izinsiz-kaldiracli-islemlere-iliskin-basin-duyurusu)
- [Capital Markets Law No. 6362, Articles 99 and 109 (Turkish, consolidated text)](https://www.mevzuat.gov.tr/mevzuatmetin/1.5.6362.pdf)

> 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](https://fincodelabs.com/en/editorial-policy).

---

Published by Fincode (Fincode Yazılım ve Teknoloji A.Ş.), a software company in Istanbul, Turkey: https://fincodelabs.com/en/blog/mt4-api

Cite as: Fincode, "MT4 API: MQL4, broker-side APIs and Python routes", updated November 6, 2026, https://fincodelabs.com/en/blog/mt4-api
