MT5 Candle Data API

SECURE

MetaTrader 5 — Live & Historical OHLCV Data

Fetch Candles
N8N Link Generator
Python Guide
Trading Use Cases
Quick Docs
Request Parameters
N8N HTTP Request — Configuration
N8N HTTP Request Node Setup
Method GET
URL
Headers X-API-Key: 1azwfMHrRd03Z4LUnVh08eaKPkFfZNNgwh8THhn1iWw

In N8N, use an HTTP Request node: Method GET, paste the URL above as URL. Add Header: X-API-Key = 1azwfMHrRd03Z4LUnVh08eaKPkFfZNNgwh8THhn1iWw. Query parameters are already in the URL — no need to add them separately.

Step 1 — Install Dependencies
pip install requests pandas
Step 2 — Fetch Candles with Your API URL
Replace the URL below with your own. Get candle data in 3 lines:
import requests

url = "https://mt5api.invoker4916.io.vn/api/v1/candles?symbol=EURUSDm&timeframe=M15&count=100"

response = requests.get(url, headers={
    "X-API-Key": "1azwfMHrRd03Z4LUnVh08eaKPkFfZNNgwh8THhn1iWw"
})

data = response.json()
print(f"Loaded {data['count']} candles from {data['from_dt']} to {data['to_dt']}")
print(data["candles"][0])
Build Your API URL
url = "https://mt5api.invoker4916.io.vn/api/v1/candles?symbol=EURUSDm&timeframe=M15&count=100"
Step 3 — Pandas Data Analysis
Convert candles to a DataFrame and compute indicators:
import requests
import pandas as pd

url = "https://mt5api.invoker4916.io.vn/api/v1/candles?symbol=EURUSDm&timeframe=H1&count=500"
headers = {"X-API-Key": "1azwfMHrRd03Z4LUnVh08eaKPkFfZNNgwh8THhn1iWw"}

data = requests.get(url, headers=headers).json()
df = pd.DataFrame(data["candles"])
df["time"] = pd.to_datetime(df["time"])
df = df.iloc[::-1].reset_index(drop=True)  # oldest first

# Simple Moving Averages
df["sma20"] = df["close"].rolling(20).mean()
df["sma50"] = df["close"].rolling(50).mean()

# RSI
delta = df["close"].diff()
gain = delta.where(delta > 0, 0).rolling(14).mean()
loss = (-delta.where(delta < 0, 0)).rolling(14).mean()
df["rsi"] = 100 - (100 / (1 + gain / loss))

# Latest values
latest = df.iloc[-1]
print(f"{latest['time'].date()} | Close: {latest['close']:.5f} | RSI: {latest['rsi']:.1f}")
print(f"SMA20: {latest['sma20']:.5f} | SMA50: {latest['sma50']:.5f}")

# Golden cross signal
if latest["sma20"] > latest["sma50"]:
    print(">>> GOLDEN CROSS — BUY signal")
elif latest["sma20"] < latest["sma50"]:
    print(">>> DEATH CROSS — SELL signal")
Step 4 — Real-time Streaming (SSE)
Receive live candle updates the moment they close:
pip install sseclient-py

import sseclient, requests, json

url = "https://mt5api.invoker4916.io.vn/api/v1/subscribe"
params = {"symbol": "XAUUSDm", "timeframe": "M1", "api_key": "1azwfMHrRd03Z4LUnVh08eaKPkFfZNNgwh8THhn1iWw"}

resp = requests.get(url, params=params,
    headers={"Accept": "text/event-stream"}, stream=True)

client = sseclient.SSEClient(resp)
for event in client.events():
    msg = json.loads(event.data)
    if msg["type"] == "snapshot":
        print(f"Loaded {len(msg['candles'])} historical candles")
    elif msg["type"] == "candle":
        c = msg["data"]
        print(f"{c['time']} | Close: {c['close']} | Vol: {c['tick_volume']}")
Quant / Backtesting — Python
Fetch 10,000 M15 candles and compute RSI + Bollinger Bands:
import requests
import pandas as pd

resp = requests.get(
    "https://mt5api.invoker4916.io.vn/api/v1/candles",
    params={"symbol": "EURUSDm", "timeframe": "M15", "count": 10000},
    headers={"X-API-Key": "1azwfMHrRd03Z4LUnVh08eaKPkFfZNNgwh8THhn1iWw"}
)
df = pd.DataFrame(resp.json()["candles"])
df["time"] = pd.to_datetime(df["time"])
df = df.iloc[::-1].reset_index(drop=True)  # oldest first

# RSI
delta = df["close"].diff()
gain = delta.where(delta > 0, 0).rolling(14).mean()
loss = (-delta.where(delta < 0, 0)).rolling(14).mean()
df["rsi"] = 100 - (100 / (1 + gain / loss))

# Bollinger Bands
df["sma20"] = df["close"].rolling(20).mean()
df["bb_lower"] = df["sma20"] - 2 * df["close"].rolling(20).std()
df["signal"] = (df["rsi"] < 30) & (df["close"] < df["bb_lower"])

print("Entry signals:", df[df["signal"]].shape[0])
HFT / Scalping — Real-time SSE Stream
Receive live M1 candle closes for Gold scalping with pin bar detection:
import sseclient, requests, json

resp = requests.get(
    "https://mt5api.invoker4916.io.vn/api/v1/subscribe",
    params={"symbol": "XAUUSDm", "timeframe": "M1", "api_key": "1azwfMHrRd03Z4LUnVh08eaKPkFfZNNgwh8THhn1iWw"},
    headers={"Accept": "text/event-stream"}, stream=True
)
client = sseclient.SSEClient(resp)
for event in client.events():
    msg = json.loads(event.data)
    if msg["type"] == "candle":
        c = msg["data"]
        o, h, l, cl = c.get("open"), c.get("high"), c.get("low"), c.get("close")
        body = abs(cl - o)
        lower_wick = min(o, cl) - l
        upper_wick = h - max(o, cl)
        # Pin bar: lower wick > 2x body, tiny upper wick
        if lower_wick > body * 2 and upper_wick < body * 0.5:
            print(f">>> BULLISH PIN BAR at {c.get('time')} | Close: {cl}")
        else:
            print(f"Close: {cl} | Vol: {c.get('tick_volume')}")
N8N — Daily Morning Alert to Telegram
Every morning at 08:00, fetch H4 candles and send a trend summary to Telegram:
# N8N Workflow:
# 1. Schedule Trigger → Daily at 08:00
# 2. HTTP Request
#    GET /api/v1/candles?symbol=XAUUSDm&timeframe=H4&count=5
#    Header: X-API-Key = 1azwfMHrRd03Z4LUnVh08eaKPkFfZNNgwh8THhn1iWw
# 3. Code (JS):
#    const candles = $json.candles;
#    const closes = candles.map(c => c.close);
#    const avg = (closes.reduce((a,b) => a+b, 0) / closes.length).toFixed(2);
#    const latest = closes[closes.length-1];
#    return { latest, avg, signal: latest > avg ? "BUY" : "SELL" };
# 4. Telegram Node:
#    Message: "{{ $json.signal }} signal | XAUUSD H4 close: {{ $json.latest }}"
N8N — Real-time Discord Alert on Candle Pattern
Alert to Discord when XAUUSD M5 closes with a bullish engulfing candle:
# N8N Workflow:
# 1. Wait (Webhook) — receives manual /push trigger
# 2. HTTP Request
#    GET /api/v1/candles?symbol=XAUUSDm&timeframe=M5&count=2&source=mql5
#    Header: X-API-Key = 1azwfMHrRd03Z4LUnVh08eaKPkFfZNNgwh8THhn1iWw
# 3. Code (JS) — detect engulfing:
const candles = $input.first().json.candles;
const prev = candles[1], curr = candles[0];
const body = Math.abs(curr.close - curr.open);
const prevBody = Math.abs(prev.close - prev.open);
const engulfing = curr.close > prev.open && curr.open < prev.close
  && body > prevBody;

if (engulfing) {
  return { json: { alert: "BULLISH ENGULFING", close: curr.close } };
}
# 4. Discord Node → Post: {{ $json.alert }} at {{ $json.close }}
Multi-Timeframe Strategy (H4 Trend + M15 Entry)
D1 sets trend direction (200 SMA), M15 triggers entries (RSI). Full Python example:
import requests

API_KEY = "1azwfMHrRd03Z4LUnVh08eaKPkFfZNNgwh8THhn1iWw"
BASE = "https://mt5api.invoker4916.io.vn/api/v1/candles"

def get_candles(symbol, tf, count=200):
    r = requests.get(BASE, params={"symbol": symbol, "timeframe": tf, "count": count},
                      headers={"X-API-Key": API_KEY})
    return r.json()["candles"]

def sma(closes, period):
    return sum(closes[-period:]) / period

def rsi(closes, period=14):
    deltas = [closes[i] - closes[i-1] for i in range(1, len(closes))]
    gain = sum([d for d in deltas[-period:] if d > 0]) / period
    loss = abs(sum([d for d in deltas[-period:] if d < 0]) / period)
    return 100 - (100 / (1 + gain / loss)) if loss != 0 else 50

# Step 1: D1 trend (200 SMA)
d1 = get_candles("EURUSDm", "D1", 200)
d1_closes = [c["close"] for c in reversed(d1)]
trend_up = d1_closes[-1] > sma(d1_closes, 200)

# Step 2: M15 entry (RSI)
m15 = get_candles("EURUSDm", "M15", 100)
m15_closes = [c["close"] for c in reversed(m15)]
r = rsi(m15_closes)

# Signal
if trend_up and r < 40:
    print(f"LONG — D1 up, RSI={r:.1f}")
elif not trend_up and r > 60:
    print(f"SHORT — D1 down, RSI={r:.1f}")
else:
    print("No signal")
All Endpoints
GET/api/v1/healthMT5 + watcher status. Use in uptime monitors
GET/api/v1/connectForce MT5 reconnect after terminal restart
GET/api/v1/symbolsList all 348 tradeable symbols
GET/api/v1/timeframesM1–MN1 supported timeframes
GET/api/v1/candlesFetch OHLCV (max 10,000). Core endpoint
GET/api/v1/pushForce MQL5 EA to push latest candles
GET/api/v1/subscribeSSE stream — live tick-by-tick data
/candles — Query Parameters
symbolEURUSDm, XAUUSDm, BTCUSDm, US500m...
timeframeM1 M5 M15 H1 H4 D1 W1 MN1
count1–10,000 candles
sourcemt5 (historical, default) or mql5 (live)
Authentication — Required on Every Request

Header: X-API-Key: 1azwfMHrRd03Z4LUnVh08eaKPkFfZNNgwh8THhn1iWw
SSE subscribe uses query param instead: ?api_key=YOUR_KEY (browsers block custom headers on EventSource)

Candle Response Format
{
  "symbol": "EURUSDm",
  "timeframe": "M15",
  "count": 5,
  "from_dt": "2026-03-27T03:00:00",
  "to_dt": "2026-03-27T03:56:00",
  "candles": [
    { "time": "2026-03-27T03:00:00",
      "open": 1.15337, "high": 1.15352,
      "low": 1.15325, "close": 1.15347,
      "tick_volume": 99 },
    ...
  ],
  "source": "mt5"
}

Swagger Docs  |  Health Check