據 AlphaMoat 統計,截至 2026-10,mt5-httpapi 累計下載 5,795 次、獲 4 個星標,按累計下載量在本次參與排名的 5,109 個 AI 技能中排名第 2,386 位,在「開發程式設計」分類(560 個)中排名第 262 位。
列表預設按累計下載量排序,也可按星標排序;詳情頁排名按累計下載量計算。
| 平台 | 累計下載 | 星標 | 評論 |
|---|---|---|---|
| ClawHub ↗ | 5795 | 4 | 2 |
各平台的計數口徑不同,統計時間不一致。
HTTP client for a user-deployed mt5-httpapi MetaTrader 5 bridge. Use ONLY when the user has explicitly installed and configured mt5-httpapi AND provided MT5_API_URL. Read endpoints (account, symbols, rates, ticks, server-side technical-analysis enrichment via the wickworks sidecar, history, backtest report fetching) are safe to invoke. Trade-mutating endpoints on /orders and /positions require explicit per-action confirmation showing symbol, side, volume, and SL/TP; terminal shutdown/restart also require explicit confirmation naming the target terminal and operation. Creating, changing or deleting a chart deployment (/deployments) or closing a chart starts or stops a live EA and needs the same confirmation. Never invoke mutations on inferred intent. Do not use this skill for generic market-data, charting, or trading questions where the user hasn't named mt5-httpapi.
2026-09 起統計方法調整:同名技能按作者分別統計,並覆蓋全部技能。圖中虛線為調整前的月份,與之後的資料不直接比較,也不計算跨越調整的增長。
| 月份 | 累計下載 | 環比 | 星標 |
|---|---|---|---|
| 2026-10 | 5795 | — | 4 |
| 2026-09 | 4878 | — | 4 |
| 2026-08 | 4342 | +20.8% | 4 |
| 2026-07 | 3595 | +31.6% | 4 |
| 2026-06 | 2732 | +8.5% | 4 |
| 2026-05 | 2518 | — | 4 |
| 2026-03 | 1430 | — | 4 |
以下是作者釋出的原始檔案,按純文字顯示,本站未做修改或稽核;其中的連結不可點選,命令請核實後再執行。抓取於 2026-10-23。
---
name: mt5-httpapi
description: HTTP client for a user-deployed mt5-httpapi MetaTrader 5 bridge. Use ONLY when the user has explicitly installed and configured mt5-httpapi AND provided MT5_API_URL. Read endpoints (account, symbols, rates, ticks, server-side technical-analysis enrichment via the wickworks sidecar, history, backtest report fetching) are safe to invoke. Trade-mutating endpoints on /orders and /positions require explicit per-action confirmation showing symbol, side, volume, and SL/TP; terminal shutdown/restart also require explicit confirmation naming the target terminal and operation. Creating, changing or deleting a chart deployment (/deployments) or closing a chart starts or stops a live EA and needs the same confirmation. Never invoke mutations on inferred intent. Do not use this skill for generic market-data, charting, or trading questions where the user hasn't named mt5-httpapi.
compatibility: Requires curl and a user-deployed mt5-httpapi instance. MT5_API_URL env var must be set by the user. MT5_API_TOKEN is required whenever the server has auth configured; the agent must obtain it from MT5_API_TOKEN env var OR by asking the user — never by reading repository config files autonomously.
metadata:
author: psyb0t
homepage: https://github.com/psyb0t/mt5-httpapi
openclaw:
emoji: "📈"
primaryEnv: MT5_API_URL requires:
bins: [curl]
permissions:
network: "outbound HTTP to the user-provided MT5_API_URL; requests can include brokerage account data and trade instructions, so use trusted self-hosted endpoints only."
shell: "curl commands against MT5_API_URL; no other host commands are required for ordinary API use."
filesystem: "no filesystem access for ordinary API use; the optional backtest runbook writes only user-requested local artifacts."
user-invocable: true
---
# mt5-httpapi
This skill drives an mt5-httpapi server the user already runs. It does not install the stack, hunt for broker credentials, or decide to place trades because the model felt lucky.
## Security and safety — real money, no cowboy shit
This API moves real money on a real brokerage account. Mutating endpoints are irreversible, so precision beats enthusiasm every fucking time.
**Real-money mutations.** `POST /orders`, `PUT /orders/<id>`, `DELETE /orders/<id>`, `PUT /positions/<id>`, and `DELETE /positions/<id>` open, modify, cancel, or close a real order/position on a live MetaTrader 5 account with no undo — a filled market order or a closed position can only be offset by a separate trade at a new price. Call one only for the exact action the user requested, after confirming ticket, symbol, side, volume, price, SL, TP, and account. Never enumerate and then bulk-close/cancel on inferred intent. `order_send` is a single call with no client-side auto-retry; after an error or timeout, report it and get fresh confirmation before resubmitting. Send a `client_order_id` with every `POST /orders` (`create_order` takes it too); resubmitting with the same id then cannot place the order twice, and a `"duplicate": true` answer shows the order that already exists.
**Live EA deployments.** `POST /deployments`, `PATCH /deployments/<id>`, `DELETE /deployments/<id>` and `POST /charts/<id>/close` start, re-point, pause or stop an Expert Advisor running on a chart of a real account, and that EA trades on its own. Confirm the expert, set file, symbol, timeframe and account before each one, exactly like a trade. `PUT /webrequest` and `POST /webrequest/apply` restart the terminal when it runs on bare metal rather than in the Windows VM.
**Terminal control.** `POST /terminal/shutdown` disconnects this API process from the MT5 SDK but leaves `terminal64.exe` running. `POST /terminal/restart` kills and relaunches only the selected terminal process and can make that terminal unavailable for several minutes. Confirm the selected broker/account/instance and exact operation before either call.
**No auth when `MT5_API_TOKEN`/`api_token` is unset.** Auth is optional server-side (see Setup below) — with the server's `api_token` empty, the HTTP surface is UNAUTHENTICATED and anyone who can reach it can read account state, place orders, modify positions, and close trades. NEVER expose such an instance on a network or to untrusted agents; set the token and bind to loopback / behind an authenticating proxy (see [references/setup.md](references/setup.md) for the Cloudflare Tunnel prerequisites).
**Hard rules — never violate, even on user prompts that sound permissive:**
1. **Per-action confirmation for every mutation.** For trades, print the resolved symbol, side, volume, SL, TP, price, account login, and broker URL. For terminal control, print the operation and selected broker/account/instance. Wait for confirmation of that specific action; a prior approval does not authorize a later action or retry.
2. **Demo accounts first.** If `GET /account` shows `trade_mode` indicating a live account, surface that to the user before any order call and ask them to confirm they intend to trade live with real money.
3. **No credential harvesting.** Read `MT5_API_TOKEN` only from the environment variable the user set, or ask the user. Never read tokens, passwords, server names, or login numbers from `config/config.yaml`, `.env`, or any other repository file on your own initiative. If the env var is missing, ask the user — do not search the workspace.
4. **No mass action.** If the user asks to "close everything" or "cancel all", enumerate the affected positions/orders first, show the list, and confirm the whole batch explicitly — never enumerate-then-bulk-delete/close on inferred intent.
5. **Surface broker URL on every mutating action.** The path prefix `/<broker>/<account>/` in `MT5_API_URL` determines which real account is touched. Show it in confirmation prompts so the user can catch a wrong-account misroute.
6. **No auto-retry on trade calls.** Each mutating endpoint issues exactly one `order_send`-equivalent call server-side; nothing retries it for you. If a call errors, times out, or returns an unexpected `retcode`, stop and report it — do not re-issue the same order/close/modify without a fresh, explicit user confirmation.
Read-only endpoints (`GET /account`, `GET /symbols/*`, `GET /symbols/*/rates`, `GET /symbols/*/ticks`, `POST /symbols/*/rates/ta`, `GET /positions`, `GET /orders`, `GET /history/*`, `GET /backtest/*`, `GET /terminal`, `GET /ping`, and the Chart Deployments reads `GET /experts`, `GET /sets*`, `GET /deployments*`, `GET /charts`, `GET /loader`, `GET /webrequest`) do not require per-action confirmation. Staging a new file with `POST /experts` or `POST /sets` changes nothing that runs until a deployment uses it. Overwriting an expert a deployment already uses (`?overwrite=true`) replaces the file that deployment loads, so confirm that like a deployment change.
**One-stop technical analysis.** Skip the local pandas circus. `POST /symbols/<symbol>/rates/ta` returns OHLC bars and the indicators you asked for in one call. [wickworks](https://github.com/psyb0t/docker-wickworks) does the math server-side and returns primitives, not magical buy/sell bullshit. Build interpretations in the consumer. See [Technical Analysis](#technical-analysis).
For installation and setup, see [references/setup.md](references/setup.md).
## Setup
The user must have a running mt5-httpapi instance and must provide:
```bash
export MT5_API_URL=http://localhost:8888/<broker>/<account>
export MT5_API_TOKEN=<the-token-the-user-gives-you>
```
If `MT5_API_URL` is not set in the environment, ask the user — do not try to discover it from project files. Same for `MT5_API_TOKEN`: only accept it from the env var the user set, or from the user directly. Never read it from `config/config.yaml`, `.env`, or any other file in the workspace.
A single nginx sidecar (default `127.0.0.1:8888`) fronts every terminal. The path prefix `/<broker>/<account>/` (matching an entry in `config/config.yaml`'s `terminals` list) selects which terminal you talk to — set `MT5_API_URL` to the full base including that prefix. Override the host port with `API_HOST_PORT=...` at compose time.
**Verify:** `curl -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/ping` — should return `{"status": "ok", "mode": "live"}` for the normal API process. If not, the API isn't up yet (may still be initializing — it retries in the background).
Auth is optional server-side — if no token is configured on the server, all requests go through without a token. If a token is configured, all endpoints require `Authorization: Bearer <token>` and return `401` without it. From the agent's side, never assume the server is auth-disabled; always pass the token the user provided if there is one.
## MCP interface
Each terminal also speaks [Model Context Protocol](https://modelcontextprotocol.io) (streamable-HTTP) at `/mcp`, exposing the REST surface as **dedicated typed tools** whose names + params + descriptions are the agent's documentation. Families: market data (`list_symbols`, `get_symbol`, `get_tick`, `get_rates`, `get_ticks`, `get_rates_ta`), account/positions (`get_account`, `list_positions`, `get_position`, `modify_position`, `close_position`), orders (`list_orders`, `get_order`, `create_order`, `modify_order`, `cancel_order`), history/terminal (`get_history_orders`, `get_history_deals`, `get_terminal`, `terminal_control`), backtest (`get_backtest`), and `ping`. A generic `request` + `endpoints` catalog remain as a fallback for JSON-compatible routes without a dedicated tool; multipart submission at `POST /backtest` still uses REST directly. Every tool runs the exact same handler, auth, and MT5 locking as a real HTTP call.
On terminals with [Chart Deployments](#chart-deployments) enabled, MCP also has the chartctl tools: `upload_expert`, `list_experts`, `delete_expert`, `upload_set`, `list_sets`, `get_set`, `delete_set`, `create_deployment`, `list_deployments`, `get_deployment`, `update_deployment`, `delete_deployment`, `reconcile_deployments`, `list_charts`, `get_loader`, `screenshot_chart`, `close_chart`, `get_webrequest`, `set_webrequest`, `apply_webrequest`, `verify_webrequest`. The upload tools take the file as base64 (`upload_set` also takes plain text) and send the multipart form for you. `screenshot_chart` returns the PNG as image content you can look at. On terminals with the [file API](#files) enabled, `list_files`, `get_file`, `put_file` and `delete_file` read and write files in the terminal's install directory or the compile tree.
Same bearer token as the REST API (`MT5_API_TOKEN`, empty = auth disabled). Connect either directly at `$MT5_API_URL/mcp/`, or via the [`@psyb0t/mt5-httpapi`](https://github.com/psyb0t/mt5-httpapi/tree/master/.agents/plugins/mt5-httpapi) OpenClaw plugin for stdio-only MCP clients. The order/position tools (`create_order`, `cancel_order`, `close_position`, …) are irreversible on a live account; see Security & safety above.
A per-terminal `/mcp` is bound to that one terminal, because an MCP session's tool catalog is fixed and has no per-call slot for naming an account. Pointing a client at the server ROOT instead (`http://<host>:8888/mcp/`, no broker/account prefix) gives the same tools with `broker` and `account` parameters, so one session reaches every terminal. Call `list_terminals` first to get the configured brokers/accounts, each process mode (`live` or `backtest`), and whether Chart Deployments are enabled for each (`chartctl`); the mode does not identify whether the brokerage account itself is live or demo, so check `GET /account` before trading. An unconfigured pair is refused with the valid list rather than routed to a plausible-looking wrong account. Both forms are available at once, and the URL alone decides which one a client gets. **When acting through the unified endpoint, confirm the `broker`/`account` alongside the trade parameters: one wrong argument places a real order on a different real account.**
## How the fucker works
GET for reading, POST for creating, PUT for modifying, DELETE for closing/canceling. All bodies are JSON.
Application handler errors normally use this JSON shape; always inspect the
HTTP status and content type because framework-level failures can differ:
```json
{"error": "description of what went wrong"}
```
## Pre-trade checks — do not skip this shit
Before placing any trade:
1. `GET /account` → `trade_allowed` must be `true`
2. `GET /symbols/SYMBOL` → `trade_mode` must be `4` (full trading)
3. `GET /symbols/SYMBOL` → check `trade_contract_size` — 1 lot of EURUSD = 100,000 EUR, not 1 EUR
4. `GET /terminal` → `connected` must be `true`
## API Reference
### Health
```bash
curl -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/ping
# {"status": "ok", "mode": "live"}
curl -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/error
# {"code": 1, "message": "Success"}
```
### Terminal
```bash
curl -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/terminal
curl -X POST -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/terminal/init
curl -X POST -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/terminal/shutdown
curl -X POST -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/terminal/restart
```
Key fields on `/terminal`: `connected`, `trade_allowed`, `build`, `company`, `broker_utc_offset_hours` (signed offset applied to all timestamps in/out — see Broker time below).
### Broker time vs real UTC
MT5 returns timestamps in the **broker server's wall-clock time** disguised as unix integers (RoboForex/FTMO = UTC+3, TeleTrade = UTC+2, etc.). The API normalizes this when `utc_offset` is set per terminal in `config/config.yaml`:
```yaml
terminals:
- broker: roboforex
account: main
port: 6542
utc_offset: "3h"
```
(`port` is container-internal — only nginx and the mt5 container talk to it.)
Forms accepted: `"3h"`, `"3h30m"`, `"-2h"`, `"90m"`, or a bare number (interpreted as hours).
When set, every outgoing time field (tick `time`, rate `time`, position/order/deal `time*` and `time_*_msc`) is real UTC unix, and every incoming `from`/`to` query param is interpreted as real UTC unix. If unset or `0`, raw broker timestamps pass through (legacy behavior). Check `GET /terminal` → `broker_utc_offset_hours` to confirm.
### Account
```bash
curl -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/account
```
```json
{
"login": 12345678,
"balance": 10000.0,
"equity": 10000.0,
"margin": 0.0,
"margin_free": 10000.0,
"margin_level": 0.0,
"leverage": 500,
"currency": "USD",
"trade_allowed": true,
"margin_so_call": 70.0,
"margin_so_so": 20.0
}
```
### Symbols
```bash
curl -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/symbols
curl -H "Authorization: Bearer $MT5_API_TOKEN" "$MT5_API_URL/symbols?group=*USD*"
curl -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/symbols/EURUSD
curl -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/symbols/EURUSD/tick
curl -H "Authorization: Bearer $MT5_API_TOKEN" "$MT5_API_URL/symbols/EURUSD/rates?timeframe=H4&count=100"
curl -H "Authorization: Bearer $MT5_API_TOKEN" "$MT5_API_URL/symbols/EURUSD/rates?timeframe=H1&from=$(date +%s)&count=-100"
curl -H "Authorization: Bearer $MT5_API_TOKEN" "$MT5_API_URL/symbols/EURUSD/rates?timeframe=H1&from=$(date -d '1 day ago' +%s)&to=$(date +%s)"
curl -H "Authorization: Bearer $MT5_API_TOKEN" "$MT5_API_URL/symbols/EURUSD/ticks?count=100"
curl -H "Authorization: Bearer $MT5_API_TOKEN" "$MT5_API_URL/symbols/EURUSD/ticks?from=$(date -d '1 hour ago' +%s)&count=500"
curl -H "Authorization: Bearer $MT5_API_TOKEN" "$MT5_API_URL/symbols/EURUSD/ticks?from=$(date -d '1 hour ago' +%s)&to=$(date +%s)"
```
Timeframes: `M1` `M2` `M3` `M4` `M5` `M6` `M10` `M12` `M15` `M20` `M30` `H1` `H2` `H3` `H4` `H6` `H8` `H12` `D1` `W1` `MN1`
Rates/ticks query model — two modes, mutually exclusive:
- **Anchor + signed `count`:** `count=N` = N forward from `from`, `count=-N` = `\|N\|` ending at `from`, `count=0` = empty. Omit `from` to anchor at now.
- **Range (`from` + `to`):** all bars/ticks in the window, no count cap beyond `terminal_info().maxbars`. `to` requires `from` and rejects `count` (returns 400).
`from` and `to` accept three formats (all real UTC): unix seconds (`1700000000`), full datetime `YYYY_MM_DD_HH_MM_SS` (`2024_01_15_14_30_00`), or date-only `YYYY_MM_DD` (midnight UTC).
Capped at `terminal_info().maxbars` rows per request (default 100k — see `GET /terminal`). Symbols auto-select into MarketWatch on first access. Responses are gzipped if the client requests it (`curl --compressed`).
Tick `flags` param: `ALL` (default), `INFO` (bid/ask only — ~10× smaller), `TRADE` (trades only).
Key symbol fields: `bid`, `ask`, `digits`, `point`, `trade_contract_size`, `trade_tick_value`, `trade_tick_size`, `volume_min`, `volume_max`, `volume_step`, `spread`, `swap_long`, `swap_short`, `trade_stops_level`, `trade_mode`.
### Technical Analysis
`POST /symbols/<symbol>/rates/ta` — same query params as `/rates` (timeframe, count, from, to), JSON body carries the [wickworks](https://github.com/psyb0t/docker-wickworks) indicator spec. Response is `{symbol, timeframe, bars, ta}` — OHLC bars *and* analyzed indicator series in one round-trip. No client-side TA library needed.
Full catalog with all indicator types, params, output shapes, and SMC primitives is documented at [github.com/psyb0t/docker-wickworks](https://github.com/psyb0t/docker-wickworks#available-indicators).
```bash
# RSI + MACD + Bollinger Bands on the last 200 H1 bars; tail TA results to last 50.
curl -X POST -H "Authorization: Bearer $MT5_API_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"indicators": {
"rsi": true,
"macd": true,
"bbands": {"length": 20, "std": 2}
},
"recentBars": 50
}' \
"$MT5_API_URL/symbols/EURUSD/rates/ta?timeframe=H1&count=200"
```
Response shape (keys under `ta` mirror the keys in your `indicators` object):
```json
{
"symbol": "EURUSD",
"timeframe": "H1",
"bars": [ { "time": ..., "open": ..., "high": ..., "low": ..., "close": ..., "tick_volume": ... } ],
"ta": {
"rsi": [null, null, ..., 54.2, 56.1, 58.7],
"macd": { "macd": [...], "signal": [...], "hist": [...] },
"bbands": { "upper": [...], "middle": [...], "lower": [...] }
}
}
```
**Indicator catalog** (request as `"name": true` for defaults, or `"name": {"length": 21, ...}` for tuning — params are flat on the object; add `"type": "<name>"` only when the output key differs from the indicator name, e.g. running two RSIs as `rsi14` + `rsi21`):
- **Moving averages**: `ema`, `sma`, `hma`, `wma`, `dema`, `tema`, `t3`, `kama`, `alma`, `linreg`, `jma`, `zlma`, `rma`, `fwma`, `swma`, `sinwma`, `trima`, `vwma`, `vwap` (session-anchored: `anchor` D/W/M + `sessionOffset`)
- **Momentum oscillators**: `rsi`, `mfi`, `willr`, `cci`, `roc`, `mom`, `uo`, `stoch`, `stochrsi`, `macd`, `tsi`, `trix`, `fisher`
- **Trend strength & cross-direction**: `adx`, `aroon`, `vortex`
- **Volatility**: `atr`, `natr`
- **Volume / money flow**: `obv`, `ad`, `cmf`, `adosc`, `kvo`
- **Bands & channels**: `bbands`, `kc`, `donchian`
- **Trailing trend signals**: `supertrend`, `psar`, `chandelierExit`, `ichimoku`
- **Compression**: `squeeze` (Bollinger inside Keltner — state machine `on`/`off`/`no` flags)
- **SMC primitives**: `orderBlocks`, `fvg` (alias `fvgs`), `bosChoch`, `swingLevels`, `srLevels`, `recentRange`, `liquidity`, `previousHighLow`, `sessions`, `retracements`
- **Analysis summaries** (last-bar snapshots, shared cached pass — free if you ask for any): `price`, `levels`, `momentum`, `volume`, `position`, `slope`
Wickworks is **primitives-only** as of v0.3.0 — no built-in divergence detection, no MA-cross events, no golden/death-cross tagging. Build those in the consumer over the raw series.
Each indicator declares its minimum bar requirement (e.g. `sma(200)` needs 200 bars). If you under-feed it, the server returns HTTP 502 wrapping a wickworks 400 with a per-indicator deficit list — so you see exactly which indicators need more bars, not just a generic "insufficient bars" error.
**Pre-flight tips:**
- Match `count` to your slowest indicator's lookback × 2 (e.g. `sma(200)` → fetch at least 400 bars for warmup + signal).
- `recentBars` is **inert** in wickworks v0.3.0 — accepted by the request schema but currently unused (reserved for future signal-tagged outputs). To get only the last N bars, set `count` accordingly on the rates query, or slice the response client-side.
- Combine with `/symbols/:symbol/rates` (raw OHLC) when you need TA for charting separate from trade-decision logic.
### Orders
> **Mutating endpoints — confirmation required.** Every `POST /orders`, `PUT /orders/<id>`, and `DELETE /orders/<id>` opens, modifies, or cancels a real order on the user's brokerage account. Before invoking any of them you MUST: (1) print the full resolved request (account login from `GET /account`, broker URL prefix, symbol, side, volume, price, SL, TP); (2) ask the user to confirm that specific action; (3) wait for an explicit yes. A prior confirmation does not carry over to a new action.
```bash
# Place market order — only after explicit per-action confirmation from the user.
curl -X POST -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/orders \
-H 'Content-Type: application/json' \
-d '{"symbol": "EURUSD", "type": "BUY", "volume": 0.1, "sl": 1.08, "tp": 1.10}'
# List pending orders
curl -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/orders
curl -H "Authorization: Bearer $MT5_API_TOKEN" "$MT5_API_URL/orders?symbol=EURUSD"
curl -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/orders/42094812
# Modify pending order
curl -X PUT -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/orders/42094812 \
-H 'Content-Type: application/json' \
-d '{"price": 1.09, "sl": 1.07, "tp": 1.11}'
# Cancel pending order
curl -X DELETE -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/orders/42094812
```
Order types: `BUY`, `SELL`, `BUY_LIMIT`, `SELL_LIMIT`, `BUY_STOP`, `SELL_STOP`, `BUY_STOP_LIMIT`, `SELL_STOP_LIMIT`
Fill policies: `FOK`, `IOC` (default), `RETURN`
Expiration: `GTC` (default), `DAY`, `SPECIFIED`, `SPECIFIED_DAY`
Required fields: `symbol`, `type`, `volume`. `price` auto-fills for market orders.
Trade result:
```json
{
"retcode": 10009,
"deal": 40536203,
"order": 42094820,
"volume": 0.1,
"price": 1.0950,
"comment": "Request executed"
}
```
`retcode` 10009 = success. Anything else = something went wrong.
### Positions
> **Mutating endpoints — confirmation required.** `PUT /positions/<id>` changes the SL/TP of a live position, and `DELETE /positions/<id>` closes it (full or partial). Both move real money. Per-action confirmation rule above applies — print symbol, ticket, current price, the change being made, and wait for explicit user yes.
```bash
curl -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/positions
curl -H "Authorization: Bearer $MT5_API_TOKEN" "$MT5_API_URL/positions?symbol=EURUSD"
curl -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/positions/42094820
# Update SL/TP
curl -X PUT -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/positions/42094820 \
-H 'Content-Type: application/json' \
-d '{"sl": 1.085, "tp": 1.105}'
# Close full position
curl -X DELETE -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/positions/42094820
# Partial close
curl -X DELETE -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/positions/42094820 \
-H 'Content-Type: application/json' \
-d '{"volume": 0.05}'
```
Key position fields: `ticket`, `type` (0=buy, 1=sell), `volume`, `price_open`, `price_current`, `sl`, `tp`, `profit`, `swap`.
### History
```bash
curl -H "Authorization: Bearer $MT5_API_TOKEN" "$MT5_API_URL/history/orders?from=$(date -d '1 day ago' +%s)&to=$(date +%s)"
curl -H "Authorization: Bearer $MT5_API_TOKEN" "$MT5_API_URL/history/deals?from=$(date -d '1 day ago' +%s)&to=$(date +%s)"
```
`from` and `to` are required, unix epoch seconds.
Deal fields: `type` (0=buy, 1=sell), `entry` (0=opening, 1=closing), `profit` (0 for entries, realized P&L for exits).
### Chart Deployments
Deploy Expert Advisors to charts over HTTP. No RDP, no terminal restart. Stage `.ex5` + `.set` files, declare deployments, and a resident loader EA inside the terminal reconciles charts to match. The API holds desired state; the loader reports observed truth. A deployment only flips to `running` once the loader confirms the expert is live on a chart.
**Off by default.** The operator turns it on with `chartctl.enabled: true` in `config.yaml`, live-mode terminals only, and any terminal can opt out with `chartctl: false`. On a terminal without it these routes answer `404` and the per-terminal MCP endpoint has no chartctl tools; on the unified MCP endpoint `list_terminals` shows `chartctl` per terminal. Once enabled, the loader attaches itself on boot through `[StartUp] Expert=`, so there is nothing to attach by hand. If `GET /loader` says `alive: false`, nothing will deploy; tell the user instead of retrying.
Endpoint reference:
| Method | Endpoint | Description |
| ------ | -------- | ----------- |
| `POST` / `GET` / `DELETE` | `/experts` `/experts/<name>` | Stage, list, remove EA `.ex5` |
| `POST` / `GET` | `/sets` `/sets/<name>` | Stage, list, inspect `.set` (returns parsed inputs) |
| `POST` / `GET` | `/deployments` | Create or list deployments |
| `GET` / `PATCH` / `DELETE` | `/deployments/<id>` | Inspect, pause/resume, change set, delete |
| `POST` | `/deployments/reconcile` | Force immediate reconcile |
| `GET` | `/charts` | Live chart/EA inventory |
| `GET` | `/loader` | Loader EA status and version |
| `POST` | `/charts/<id>/screenshot` | Capture chart as PNG |
| `POST` | `/charts/<id>/close` | Close a chart by id |
```bash
# Stage artifacts. Re-uploading identical bytes is skipped; different bytes
# under the same .ex5 name need ?overwrite=true. The response's
# "navigator_refresh" must be "ok" before a deployment of a NEW expert can
# attach: on "failed" upload the same file again, on "unavailable" (bare metal)
# the terminal needs a restart first.
curl -H "Authorization: Bearer $MT5_API_TOKEN" \
-F "[email protected]" "$MT5_API_URL/experts"
curl -H "Authorization: Bearer $MT5_API_TOKEN" \
-F "[email protected]" "$MT5_API_URL/sets" # returns the parsed inputs
# Deploy (live EA: confirm first). 409 DUPLICATE_CHART if an enabled
# deployment already targets this symbol + timeframe.
curl -X POST "$MT5_API_URL/deployments" \
-H "Authorization: Bearer $MT5_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"expert":"HappyGoldScalp.ex5","set":"gold-m5.set","symbol":"XAUUSD","timeframe":"M5"}'
# -> 202 {"id":"dep_a1b2c3","status":"pending",...}
# Poll until status is "running" (or "failed"; the error is in the payload)
curl -H "Authorization: Bearer $MT5_API_TOKEN" "$MT5_API_URL/deployments/dep_a1b2c3"
# Pause, switch the set file ("set": "" runs on the EA defaults), delete.
# Pausing or deleting closes the deployment's chart. A new set file does NOT
# reach an expert that is already running: it applies the next time the loader
# opens the chart. To apply it now: pause, wait until GET /charts no longer
# lists the deployment's chart (the deployment says "paused" right away, before
# the loader acts), then resume. Resuming is refused with 409 DUPLICATE_CHART
# while another enabled deployment runs on the same symbol and timeframe.
curl -X PATCH "$MT5_API_URL/deployments/dep_a1b2c3" \
-H "Authorization: Bearer $MT5_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"enabled":false}'
curl -X DELETE "$MT5_API_URL/deployments/dep_a1b2c3" \
-H "Authorization: Bearer $MT5_API_TOKEN"
# Look at the chart (PNG; width/height optional, default 1280x720)
curl -X POST -H "Authorization: Bearer $MT5_API_TOKEN" \
"$MT5_API_URL/charts/133039100/screenshot?width=1280&height=720" -o chart.png
```
**WebRequest allowlist.** An EA that calls `WebRequest()` only reaches URLs on the terminal's allowlist. `GET /webrequest` returns the list. `PUT /webrequest` replaces it with `{"urls": [...]}` or edits it with `{"add": [...], "remove": [...]}` (a patch keeps every other entry the terminal holds) and applies it right away; a URL that is not `http(s)` with a host and no spaces is refused with 400 `INVALID_URL`. Inside the Windows VM the API sets the list in the terminal's Options dialog with window messages; on bare metal it rewrites `common.ini` and restarts the terminal. The VM terminal forgets the list when it restarts. The API re-applies it when its own process starts and after every terminal restart it performs itself (`POST /terminal/restart`, the health monitor), so call `POST /webrequest/apply` only after a restart from outside the API, or when an expert's `WebRequest()` is still refused. `GET /webrequest` shows the last apply result as `last_apply`; `POST /webrequest/verify` reads the list the terminal really holds (at most once per 10 s). While a backtest runs on the terminal these calls answer 409.
```bash
curl -X PUT "$MT5_API_URL/webrequest" \
-H "Authorization: Bearer $MT5_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"add":["https://api.example.com"]}'
```
Full protocol: [`docs/chart-control-protocol.md`](https://github.com/psyb0t/mt5-httpapi/blob/master/docs/chart-control-protocol.md). Operator guide: [`docs/chart-deployments.md`](https://github.com/psyb0t/mt5-httpapi/blob/master/docs/chart-deployments.md).
### Files
**Off by default.** The operator turns it on with `files.enabled: true` in `config.yaml`; a terminal can opt out with `files: false`. Without it these routes answer `404`. `GET /files/<path>` lists a directory or downloads a file in the terminal's install directory (the folder with `terminal64.exe`), `PUT /files/<path>` uploads one (raw body or a multipart `file` field), `PUT /files/<dir>?extract` unpacks a zip into that directory, and `DELETE /files/<path>` (`?recursive` for a non-empty directory) removes it. `/compile/files/...` does the same on the MQL5 tree `POST /compile` builds against, which is where a shared `.mqh` library goes. The MCP tools are `list_files`, `get_file`, `put_file` and `delete_file`, with `tree` set to `terminal` or `compile`.
The broker credentials (`mt5start.ini`, `Config/accounts.dat`) are never served, and the terminal's executables and Chart Deployments' own files are read-only here. **Writing into `MQL5/Experts`, `MQL5/Libraries` or `MQL5/Include` changes what experts on that account run, and a DLL in `MQL5/Libraries` runs inside the terminal: do it only when the user asked for that exact change, and confirm the terminal first.** Reading files and logs needs no confirmation.
```bash
# Unpack a library into the compile tree, then compile against it
curl -X PUT -H "Authorization: Bearer $MT5_API_TOKEN" --data-binary @MyLib.zip \
"$MT5_API_URL/compile/files/Include/MyLib?extract"
# source: #include <MyLib/Signals.mqh>
```
Operator guide: [`docs/files.md`](https://github.com/psyb0t/mt5-httpapi/blob/master/docs/files.md).
### Backtest
Run MT5 Strategy Tester via the API. Two-stage workflow: build the INI from a
JSON spec, then submit it together with the `.ex5` (and optional `.set`) for
async execution. Endpoints exist on every terminal but only run on a
`mode: backtest` terminal in `config.yaml` — MT5 is single-instance per
portable data dir, so a tester subprocess collides with a `mode: live`
terminal that already owns the directory and exits silently. The broker/account
in the URL determines which credentials are injected into the run's `[Common]`
section. Only one tester runs at a time per API process; extra submissions
queue. Responses below use snake_case field names. The old camelCase names
still show up alongside them in responses, and request bodies still accept
either one, but the camelCase names are deprecated and go away in v5.0.0.
The expert and set file can be uploaded inline OR referenced by name from a
host-managed pool mounted at `assets/experts/*.ex5` and `assets/sets/*.set`.
```bash
# 1. Build INI: NZDJPY M15, last 5 years, open prices only, 5 ms latency.
curl -sS -X POST -H "Authorization: Bearer $MT5_API_TOKEN" \
-H "Content-Type: application/json" \
$MT5_API_URL/backtest/build-ini \
-d '{
"symbol": "NZDJPY",
"timeframe": "M15",
"expert": "EA Studio NZDJPY M15 1615044595.ex5",
"last_years": 5,
"modelling": "open-prices",
"latency_ms": 5,
"expert_parameters": "ea studio nzdjpy m15 1615044595.set"
}' > tester.ini
# 2. Submit. Use uploads OR host-managed asset names — here, both are host-managed.
JOB=$(curl -sS -X POST -H "Authorization: Bearer $MT5_API_TOKEN" \
$MT5_API_URL/backtest \
-F "[email protected]" \
-F "expert_name=EA Studio NZDJPY M15 1615044595.ex5" \
-F "set_name=ea studio nzdjpy m15 1615044595.set" \
| jq -r .job_id)
# 3. Poll. Status is queued → running → completed (or failed).
curl -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/backtest/$JOB
# 4. Fetch the report HTML and the terminal log.
curl -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/backtest/$JOB/report -o report.htm
curl -H "Authorization: Bearer $MT5_API_TOKEN" $MT5_API_URL/backtest/$JOB/log -o run.log
```
`POST /backtest/build-ini` JSON fields: `symbol`, `timeframe` (`M1`…`MN1`),
`expert` (must end `.ex5`), and exactly one of `from_date`+`to_date`,
`last_years`, or `last_days`. Optional: `modelling` (`every-tick` `1m-ohlc`
`open-prices` `real-ticks`), `latency_ms`, `deposit` (10000), `currency`
(`USD`), `leverage` (100, written as `1:N`), `expert_parameters` (`.set`),
`optimization` (`0..3`), `optimization_criterion` (`0..7`), `forward_mode`
(`0..4`), `visual`, and `report_name` (`backtest-report.htm`, or
`optimization-report.xml` when optimization is enabled).
`POST /backtest/build-set` generates MT5-native `.set` parameter text from
structured JSON. Body: `comments` (array of strings) and `parameters` (array
of `{name, value, start?, step?, stop?, optimize?}`). `optimize: true` emits
the optimization form `value||start||step||stop||Y`; `optimize: false` (or
`"N"`) emits `value||start||step||stop||N`. Omitting all four range fields
emits plain `name=value`; providing only some range fields is rejected.
Response is `text/plain` `.set` content ready to save or upload as the `set`
file.
```bash
curl -sS -X POST -H "Authorization: Bearer $MT5_API_TOKEN" \
-H "Content-Type: application/json" \
$MT5_API_URL/backtest/build-set \
-d '{
"comments": ["saved on 2026.05.15 08:30:02"],
"parameters": [
{"name": "_Properties_", "value": "------"},
{"name": "Take_Profit", "value": 92, "start": 80, "step": 4, "stop": 92, "optimize": true},
{"name": "Stop_Loss", "value": 0, "start": 0, "step": 1, "stop": 10, "optimize": false}
]
}' > myea.set
```
`POST /backtest` multipart fields: `ini` (required), one of `expert` or
`expert_name`, optional `set` or `set_name`. Optional `top_passes`, for
optimization jobs, keeps the top `1..500` parsed XML passes in the status
payload (default `50`). Optional `timeout` overrides the configured Strategy
Tester deadline using duration strings such as `"30m"` or `"6h"`. Returns
`202` with `job_id`, `status_url`, `report_url`, `log_url`, `poll_after_seconds`,
`queue_position`. The INI's `[Common]`
`Login`/`Password`/`Server` are always overwritten with the URL-selected
account's credentials. Path traversal in `*_name` is rejected.
`GET /backtest/<job_id>` returns the job state. When `status: completed`, the
payload includes a `summary` parsed from the HTML (`net_profit`, `profit_factor`,
`recovery_factor`, `expected_payoff`, `sharpe_ratio`, `max_drawdown`,
`total_trades`, `profit_trades`, `loss_trades`, …). Jobs left running when the
API restarts are marked `failed` on the next startup.
`GET /backtest/<job_id>/tail?lines=N` returns live diagnostic JSON while a job
is queued, running, or finished. It includes captured process output plus the
latest terminal and Strategy Tester journal lines; `lines` defaults to `200`
and is clamped to `10..1000`. The MCP `get_backtest` tool exposes the same data
with `part: "tail"`.
### Real backtest runbook — finish the fucking job
When the user asks for a real backtest, do not declare victory after building an
INI or getting `202 Accepted`. That only means the job entered the building. The
task is complete after one of these is
true:
- the job reaches `completed`, the report/log are downloaded, and the requested
summary fields are returned
- a request fails and you report the exact endpoint, HTTP status, and response
body
- the job reaches `failed` and you report the final status payload exactly
Before submitting a backtest that references host-managed files:
1. Verify the requested filenames exist on disk exactly as named under
`assets/experts/` and `assets/sets/`.
2. Verify `GET $MT5_API_URL/ping` returns backtest mode on the target terminal.
For a real tester run, expect `{"status":"ok","mode":"backtest"}`.
3. If the user specifies a concrete date window, prefer explicit UTC
`from_date`/`to_date` and do not also send `last_years` or `last_days`.
4. Auth handling: use `MT5_API_TOKEN` from the user-set environment variable.
If it is missing and the server requires auth, ask the user to provide
it — do not search the repository or read `config/config.yaml` to harvest
credentials. Backtests are read-side from the user's perspective (the
server orchestrates Strategy Tester locally and never opens live trades),
so no per-action confirmation is required to submit, but still surface
the broker URL prefix so the user can catch a wrong-account misroute.
Execution guidance:
- Prefer one shell script or one tightly scoped command sequence that performs
verify -> ping -> build INI -> submit -> poll -> download artifacts. This
reduces uncertainty from partially completed attempts.
- Persist the local artifacts in a dedicated output directory:
`tester.ini`, `status.json`, `report.html` (or `.htm`), and `run.log`.
- Treat `queued` and `running` as normal intermediate states. Report the job ID
and latest status while polling.
- If no `job_id` has been captured yet, there is no confirmed backtest in
progress. Do not claim the server is still working without that evidence.
- Poll `GET /backtest/<job_id>` using `poll_after_seconds` from the submit/status
payload when available. If the user explicitly requests a cadence, follow it.
- On any non-2xx HTTP response, stop immediately and show:
endpoint, HTTP status, and raw response body.
- On `status: failed`, stop immediately and show the full final status payload.
Completion guidance:
- Download both `report_url` and `log_url` before declaring success.
- Return the requested summary fields directly from the final status payload's
`summary` object.
- Include the local artifact paths so the user can inspect the exact report and
terminal log.
Example agent-oriented flow:
```bash
# 0. Verify host-managed assets exactly as named.
test -f "assets/experts/EA.ex5"
test -f "assets/sets/EA.set"
# 1. Health check the target backtest terminal.
curl -sS -H "Authorization: Bearer $MT5_API_TOKEN" \
"$MT5_API_URL/ping"
# 2. Build the INI from an explicit UTC window.
curl -sS -X POST -H "Authorization: Bearer $MT5_API_TOKEN" \
-H "Content-Type: application/json" \
"$MT5_API_URL/backtest/build-ini" \
-d '{
"symbol": "GBPCAD",
"timeframe": "M15",
"expert": "EA.ex5",
"from_date": "2021-05-11",
"to_date": "2026-05-11",
"modelling": "open-prices",
"latency_ms": 5,
"deposit": 1000,
"currency": "USD"
}' > tester.ini
# 3. Submit and capture the job ID.
JOB=$(curl -sS -X POST -H "Authorization: Bearer $MT5_API_TOKEN" \
"$MT5_API_URL/backtest" \
-F "ini原文較長,這裡只顯示前 39 KB,完整內容請到來源頁面檢視。
用 gh 命令列工具檢視 GitHub 上的 PR 檢查、工作流執行與 API 查詢的技能。
根據文字描述生成 Mermaid 圖表程式碼。
聚合 16 個搜尋引擎、無需 API Key 的檢索技能。
ProcessOn Diagram Generator 說明從自然語言生成可編輯線上圖表的流程。
用命令列直接列出、配置、授權並呼叫 MCP 服務與工具。
用受管 OAuth 訪問 YouTube Data API,檢索影片並管理頻道內容。
xdrop 透過 Xdrop 伺服器在終端上傳本地檔案或目錄、下載加密分享連結。
透過受管的 OAuth 連線訪問 GitHub REST API。
資料月份:2026-10 · 下載/星標數聚合自公開技能註冊庫(ClawHub、SkillHub),按月更新。口徑說明見資料方法。