REST and WebSocket API project for MetaTrader 5
Project description
open-api-mt5
MetaTrader 5 API service with FastAPI.
Important limitation
This API controls a single MT5 terminal/session instance per running service process.
- A single API instance can be connected to only one account at a time.
/account/connectswitches that single active session.- If you run multiple API services, use separate MT5 terminal instances/data folders for reliable isolation.
Setup
- Create a virtual environment:
- Windows PowerShell:
python -m venv .venv
- Windows PowerShell:
- Activate it:
.\.venv\Scripts\Activate.ps1
- Install dependencies:
python -m pip install -U pippip install -e .
MT5 startup config
The API initializes MetaTrader 5 when FastAPI starts and closes it when FastAPI stops. It also checks MT5 connection every 5 seconds and tries to reconnect automatically if disconnected.
Set these environment variables in PowerShell before running:
$env:MT5_PATH = "C:\Program Files\MetaTrader 5\terminal64.exe"
$env:MT5_LOGIN = "12345678"
$env:MT5_PASSWORD = "your-password"
$env:MT5_SERVER = "YourBroker-Server"
MT5_PATH is optional if MT5 is already discoverable, but setting it is recommended.
Mode, apiKey, apiSecret, and registryUrl are startup settings and are not stored by /account/connect.
Run
open-api-mt5
Optional flags:
open-api-mt5 --port 9000
open-api-mt5 --host 0.0.0.0 --port 8000
open-api-mt5 --mode standalone
open-api-mt5 --mode secure --api-key your-api-key
open-api-mt5 --mode secure-client --api-key your-api-key --api-secret your-api-secret
open-api-mt5 --registry-url https://example.com/registry
open-api-mt5 --reload
Default port is 8000.
API docs:
- Swagger UI:
http://127.0.0.1:8000/docs - WebSocket docs in Swagger:
GET /ws/positions/open/docs
Health endpoint:
GET http://127.0.0.1:8000/health
Bars endpoints:
GET http://127.0.0.1:8000/bars/{symbol}?timeframe=M1&n=100GET http://127.0.0.1:8000/bars/{symbol}/range?timeframe=M1&fromDate=2026-03-20T08:00:00Z&toDate=2026-03-20T12:00:00ZGET http://127.0.0.1:8000/quotes/{symbol}GET http://127.0.0.1:8000/ticks/{symbol}?count=100GET http://127.0.0.1:8000/market-depth/{symbol}GET http://127.0.0.1:8000/exposureGET http://127.0.0.1:8000/exposure/{symbol}
Account connection endpoints:
POST http://127.0.0.1:8000/account/connect- Body:
username,password,server, optionalpath - Example body:
{ "username": "12345678", "password": "your-password", "server": "YourBroker-Server", "path": "C:\\Program Files\\MetaTrader 5\\terminal64.exe" }
- Body:
POST http://127.0.0.1:8000/account/disconnect- If
--registry-urlis set at startup, the API sends aPOSTcall to that URL with JSON body fieldsaddress,port,apiKey, andaccountId
Security modes:
- Set the mode when starting the app with
--mode standalone,--mode secure, or--mode secure-client - Set the headers credentials when starting the app with
--api-keyand, forsecure-client,--api-secret - Set the registry target when starting the app with
--registry-url standalone: default mode, noX-apiKeyorX-apiSecretheader checkssecure: every HTTP endpoint and the open positions WebSocket requireX-apiKeyto match the locally storedapiKeysecure-client: every HTTP endpoint and the open positions WebSocket require bothX-apiKeyandX-apiSecretto match the locally stored values
Server info endpoint:
GET http://127.0.0.1:8000/api/server/info- Returns JSON with the locally stored
apiKeyand the detected machineipAddress
Trade history endpoint:
GET http://127.0.0.1:8000/trades/history- Optional query params:
fromDate,toDate(ISO datetime, UTC recommended) - If omitted, it returns the last 7 days by default
Modify an open position's stop loss / take profit:
POST http://127.0.0.1:8000/positions/modify- Body:
ticket, optionalsl, optionaltp, optionalcomment - At least one of
slortpis required. If one is omitted, its current MT5 value is kept. - Example body:
{ "ticket": 123456789, "sl": 1.0825, "tp": 1.095 }
- Body:
Open position details:
GET http://127.0.0.1:8000/positions/{ticket}/details- Returns
entryPrice,stopLossPrice,takeProfitPrice,volume,contractSize,stopLossValue, andtakeProfitValue - Value formula:
- Buy stop loss:
(entryPrice - stopLossPrice) * volume * contractSize - Buy take profit:
(takeProfitPrice - entryPrice) * volume * contractSize - Sell stop loss:
(stopLossPrice - entryPrice) * volume * contractSize - Sell take profit:
(entryPrice - takeProfitPrice) * volume * contractSize
- Buy stop loss:
Adjust an open position's stop loss / take profit by money values:
POST http://127.0.0.1:8000/positions/adjust-by-money- Body:
ticket, optionalstopLossValueInMoney, optionaltakeProfitValueInMoney, optionalcomment - Defaults:
stopLossValueInMoney = 10,takeProfitValueInMoney = 30 - The API converts money values to SL/TP price distances using the position entry price, volume, and symbol contract size.
- If the exact value cannot be represented by the symbol price step, the API uses the nearest lower value.
- Example body:
{ "ticket": 123456789, "stopLossValueInMoney": 10, "takeProfitValueInMoney": 30 }
- Response includes
stopLossPrice,takeProfitPrice,stopLossValueInMoney, andtakeProfitValueInMoneyafter rounding.
- Body:
Calendar events endpoint:
GET http://127.0.0.1:8000/calendar/events- Optional query params:
fromDate,toDate(ISO datetime),country(example:US),currency(example:USD) - Default range when omitted: last 7 days to next 7 days
WebSocket streams
Open positions stream:
ws://127.0.0.1:8000/ws/positions/open- Optional query param:
intervalSeconds(poll interval, bounded to 0.2..60) - Events:
subscribedpositionsSnapshoterror
positionsSnapshotincludes:positions[].pnl(position PnL, sourced from MT5profit)totalPnl(sum of all open positions PnL)
Example JavaScript client:
const ws = new WebSocket("ws://127.0.0.1:8000/ws/positions/open?intervalSeconds=1");
ws.onmessage = (event) => {
const payload = JSON.parse(event.data);
console.log(payload.event, payload);
};
Build and publish package
- Build distribution files:
python -m pip install --upgrade build twine
python -m build
- Upload to PyPI:
python -m twine upload dist/*
- Install from PyPI and run:
pip install open-api-mt5
open-api-mt5 --port 8000
Optional: standalone executable (no Python required on target machine)
If you want users to run it without installing Python, build an executable:
python -m pip install pyinstaller
pyinstaller --onefile --name open-api-mt5 app/cli.py
The executable will be in dist/open-api-mt5.exe.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file open_api_mt5-0.5.0.tar.gz.
File metadata
- Download URL: open_api_mt5-0.5.0.tar.gz
- Upload date:
- Size: 23.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
023c77c9cc10fe252c3d8575a45974e37eab723d3180bd47dd860ed9258aa094
|
|
| MD5 |
dcedef9961eec5d56a14dad122bf1edc
|
|
| BLAKE2b-256 |
a45c6729a02bfa325aa33863ffa7110ca24c00584a17892ae9750f5475742e29
|
File details
Details for the file open_api_mt5-0.5.0-py3-none-any.whl.
File metadata
- Download URL: open_api_mt5-0.5.0-py3-none-any.whl
- Upload date:
- Size: 26.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f825b2abf561f6a4b8c714487ec2d6aeef291c3cea5a0cde39564833dc1b78c7
|
|
| MD5 |
74807e62eefcba051374cfd4db26b096
|
|
| BLAKE2b-256 |
af327b1d8d6ada7316a8f6165e5d9855668ae47da290788722d60f780eb6d726
|