# Mt5Bridge — MT5 HTTP API 网关 通过 HTTP REST API 操控 MetaTrader 5,可部署在 Windows 云服务器上 7×24 运行。 --- ## 架构 ``` 任意语言 (Python / Rust / Node / Go / ...) │ ▼ HTTP REST API (带 API Key 认证) │ Mt5Bridge (C# + MtApi5) ← 通过端口映射暴露到公网 │ ▼ localhost:8228 MtApi5 EA (MT5 图表上运行) │ ▼ MetaTrader 5 客户端 ``` --- ## 前置条件 | 依赖 | 说明 | |------|------| | .NET 8 SDK | 本地编译(只需编译一次) | | .NET 8 ASP.NET Core Runtime | 部署目标主机上安装 | | MetaTrader 5 客户端 | 已登录任意账户 | | MtApi5 EA | 挂载在 MT5 任意图表上,默认监听端口 8228 | | MtApi5 安装包 | 安装后生成 `MT5Connector.dll` 等依赖 | --- ## 一、本地编译 ```powershell cd Mt5Bridge dotnet build -c Debug ``` 编译产物在 `bin\Debug\net8.0\`,包含以下文件: | 文件 | 说明 | |------|------| | `Mt5Bridge.exe` | 可执行入口 | | `Mt5Bridge.dll` | 编译后的主程序 | | `Mt5Bridge.runtimeconfig.json` | .NET 运行时配置 | | `Mt5Bridge.deps.json` | 依赖描述 | | `MtApi5.dll` | C# 端 MT5 通信库 | | `MtClient.dll` | MT5 客户端通信库 | | `Newtonsoft.Json.dll` | JSON 序列化 | --- ## 二、部署到目标主机 ### 1. 安装 .NET 8 Runtime 下载 .NET 8 ASP.NET Core Runtime(Windows x64):https://dotnet.microsoft.com/en-us/download/dotnet/8.0 如果是下载 SDK 压缩包,解压后将内容复制到 `C:\Program Files\dotnet\`: ```powershell Copy-Item -Path "解压目录\*" -Destination "C:\Program Files\dotnet\" -Recurse -Force ``` 验证安装: ```powershell dotnet --list-runtimes ``` 应看到 `Microsoft.NETCore.App 8.0.x` 和 `Microsoft.AspNetCore.App 8.0.x`。 ### 2. 部署文件 将 `bin\Debug\net8.0\` 整个文件夹复制到目标主机,例如 `C:\Mt5Bridge\`。 ### 3. 安装 MtApi5 在目标主机上运行 MtApi5 安装包(MSI),这会安装 `MT5Connector.dll` 等系统级依赖。 ### 4. 挂载 EA 将 `MtApi5.ex5` 复制到 MT5 的 `MQL5\Experts\` 目录,在 MT5 任意图表上挂载运行。 ### 5. 启动验证 ```powershell cd C:\Mt5Bridge dotnet Mt5Bridge.dll ``` 看到以下输出即成功: ``` CommandTimeout set to 120000ms Connecting to MT5 via MtApi5 on port 8228... MT5 Connection: Connected MT5 Bridge ready on http://localhost:8080 ``` --- ## 三、配置 API Key 编辑 [Program.cs](Program.cs),修改第 34 行的 API Key: ```csharp const string API_KEY = "你的随机密码"; ``` 生成随机密码: ```powershell -join ((48..57) + (65..90) + (97..122) | Get-Random -Count 32 | %{[char]$_}) ``` 修改后重新编译,将新的 `Mt5Bridge.dll` 覆盖到目标主机。 ### 更新 DLL(服务运行时) Bridge 作为后台服务运行时,文件被锁定无法直接覆盖。需要先停止再覆盖: ```powershell # 阻止任务计划再次触发 Stop-ScheduledTask -TaskName "Mt5Bridge" # 强制结束当前进程 taskkill /f /im dotnet.exe # 现在可以覆盖 Mt5Bridge.dll 了 # 重新启动 Start-ScheduledTask -TaskName "Mt5Bridge" ``` --- ## 四、端口映射(公网访问) ### 云服务商端口映射 在云服务商控制台配置端口映射,例如: | 字段 | 值 | |------|-----| | 类型 | TCP | | 公网端口 | 13485 | | 内网端口 | 8080 | | 说明 | Mt5Bridge | ### Windows 防火墙 如果云服务商不自动放通,手动添加防火墙规则: ```powershell New-NetFirewallRule -Name "Mt5Bridge" -DisplayName "Mt5Bridge 8080" -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow ``` --- ## 五、注册为后台服务(开机自启) 使用 Windows 任务计划程序,让 Bridge 开机自动启动、崩溃自动重启。 ### 安装 ```powershell $action = New-ScheduledTaskAction -Execute "C:\Program Files\dotnet\dotnet.exe" -Argument "Mt5Bridge.dll" -WorkingDirectory "C:\Mt5Bridge" $trigger = New-ScheduledTaskTrigger -AtStartup $settings = New-ScheduledTaskSettingsSet -StartWhenAvailable -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1) Register-ScheduledTask -TaskName "Mt5Bridge" -Action $action -Trigger $trigger -Settings $settings Start-ScheduledTask -TaskName "Mt5Bridge" ``` ### 管理命令 ```powershell # 查看状态 Get-ScheduledTask -TaskName "Mt5Bridge" | Get-ScheduledTaskInfo # 停止 Stop-ScheduledTask -TaskName "Mt5Bridge" # 重启 Start-ScheduledTask -TaskName "Mt5Bridge" # 删除 Unregister-ScheduledTask -TaskName "Mt5Bridge" -Confirm:$false ``` --- ## 六、API 接口 所有接口均需认证,支持两种方式: **方式一:Header(推荐,适用于代码调用)** ``` X-API-Key: 你的密码 ``` **方式二:URL 参数(适用于浏览器直接访问)** ``` ?key=你的密码 ``` 示例: ``` http://IP:端口/health?key=你的密码 ``` ### 健康检查 ``` GET /health ``` **响应示例:** ```json { "status": "healthy", "mt5_connected": true, "mt5_version": "unknown", "api_version": "1.0.0" } ``` ### 账户信息 ``` GET /account ``` **响应字段:** | 字段 | 类型 | 说明 | |------|------|------| | login | number | 账户号 | | leverage | number | 杠杆 | | balance | number | 余额 | | equity | number | 净值 | | profit | number | 浮动盈亏 | | margin | number | 已用保证金 | | margin_free | number | 可用保证金 | | margin_level | number | 保证金比例 | | currency | string | 账户币种 | | server | string | 服务器名 | | name | string | 账户名称 | | company | string | 经纪商 | | trade_allowed | bool | 是否允许交易 | | trade_expert | bool | 是否允许 EA 交易 | ### 品种信息 ``` GET /symbols/{symbol} ``` **示例:** `/symbols/XAUUSDc` **响应字段:** | 字段 | 类型 | 说明 | |------|------|------| | name | string | 品种名称 | | description | string | 描述 | | digits | number | 小数位数 | | point | number | 点值 | | bid | number | 卖价 | | ask | number | 买价 | | spread | number | 点差 | | spread_float | bool | 是否浮动点差 | | volume_min | number | 最小手数 | | volume_max | number | 最大手数 | | volume_step | number | 手数步长 | | trade_contract_size | number | 合约大小 | | currency_base | string | 基础货币 | | currency_profit | string | 利润货币 | | category | string | 分类路径 | ### 实时 Tick ``` GET /symbols/{symbol}/tick ``` **示例:** `/symbols/XAUUSDc/tick` **响应字段:** | 字段 | 类型 | 说明 | |------|------|------| | time | string | 时间 | | bid | number | 卖价 | | ask | number | 买价 | | last | number | 最新成交价 | | volume | number | 成交量 | | time_msc | string | 毫秒级时间 | | volume_real | number | 真实成交量 | ### 历史 K 线 ``` GET /rates/from-pos?symbol={symbol}&timeframe={timeframe}&start_pos={start}&count={count} ``` **参数说明:** | 参数 | 说明 | |------|------| | symbol | 品种名称 | | timeframe | 周期:`TIMEFRAME_M1` / `M5` / `M15` / `M30` / `H1` / `H4` / `D1` | | start_pos | 起始位置(0=最新) | | count | 获取数量 | **示例:** `/rates/from-pos?symbol=XAUUSDc&timeframe=TIMEFRAME_H1&start_pos=0&count=100` **响应字段:** | 字段 | 类型 | 说明 | |------|------|------| | time | string | 开盘时间 | | open | number | 开盘价 | | high | number | 最高价 | | low | number | 最低价 | | close | number | 收盘价 | | tick_volume | number | Tick 成交量 | | spread | number | 点差 | | real_volume | number | 真实成交量 | ### 当前持仓 ``` GET /positions ``` **响应字段:** | 字段 | 类型 | 说明 | |------|------|------| | ticket | number | 持仓编号 | | symbol | string | 品种 | | type | number | 类型(0=买, 1=卖) | | volume | number | 手数 | | price_open | number | 开仓价 | | sl | number | 止损价 | | tp | number | 止盈价 | | price_current | number | 当前价 | | swap | number | 隔夜息 | | profit | number | 盈亏 | | comment | string | 注释 | | magic | number | Magic Number | ### 挂单 ``` GET /orders?symbol={symbol} ``` symbol 为可选参数,不传则返回所有挂单。 ### 订单预检 ``` POST /order/check ``` **请求体:** ```json { "action": 1, "symbol": "XAUUSDc", "volume": 0.01, "order_type": 0, "price": 4180.0, "sl": 4170.0, "tp": 4190.0, "magic": 123456, "comment": "test", "deviation": 10 } ``` | 字段 | 类型 | 说明 | |------|------|------| | action | number | 交易操作类型 | | symbol | string | 品种 | | volume | number | 手数 | | order_type | number | 订单类型 | | price | number | 价格 | | sl | number | 止损 | | tp | number | 止盈 | | magic | number | Magic Number | | comment | string | 注释 | | deviation | number | 偏差 | ### 下单 ``` POST /order/send ``` **请求体:** ```json { "request": { "action": 1, "symbol": "XAUUSDc", "volume": 0.01, "order_type": 0, "price": 4180.0, "sl": 4170.0, "tp": 4190.0, "magic": 123456, "comment": "test", "deviation": 10 } } ``` ### 历史成交 ``` GET /history/deals?date_from={from}&date_to={to}&symbol={symbol} ``` **示例:** `/history/deals?date_from=2026-07-01&date_to=2026-07-03&symbol=XAUUSDc` --- ## 七、调用示例 ### 浏览器 直接在地址栏输入(带 `?key=` 参数): ``` http://IP:端口/health?key=你的密码 http://IP:端口/account?key=你的密码 http://IP:端口/symbols/XAUUSDc/tick?key=你的密码 ``` ### PowerShell ```powershell # 健康检查 Invoke-RestMethod -Uri "http://IP:端口/health" -Headers @{"X-API-Key"="你的密码"} # 账户信息 Invoke-RestMethod -Uri "http://IP:端口/account" -Headers @{"X-API-Key"="你的密码"} # 实时行情 Invoke-RestMethod -Uri "http://IP:端口/symbols/XAUUSDc/tick" -Headers @{"X-API-Key"="你的密码"} # 获取 100 根 H1 K 线 Invoke-RestMethod -Uri "http://IP:端口/rates/from-pos?symbol=XAUUSDc&timeframe=TIMEFRAME_H1&start_pos=0&count=100" -Headers @{"X-API-Key"="你的密码"} ``` ### Python ```python import requests BRIDGE = "http://IP:端口" HEADERS = {"X-API-Key": "你的密码"} # 健康检查 resp = requests.get(f"{BRIDGE}/health", headers=HEADERS) print(resp.json()) # 账户信息 resp = requests.get(f"{BRIDGE}/account", headers=HEADERS) print(resp.json()) # 实时行情 resp = requests.get(f"{BRIDGE}/symbols/XAUUSDc/tick", headers=HEADERS) tick = resp.json() print(f"Bid: {tick['data'][0]['bid']}, Ask: {tick['data'][0]['ask']}") # 获取 K 线 resp = requests.get(f"{BRIDGE}/rates/from-pos", headers=HEADERS, params={ "symbol": "XAUUSDc", "timeframe": "TIMEFRAME_H1", "start_pos": 0, "count": 100 }) print(resp.json()) # 下单 resp = requests.post(f"{BRIDGE}/order/send", headers=HEADERS, json={ "request": { "action": 1, "symbol": "XAUUSDc", "volume": 0.01, "order_type": 0, "price": 4180.0, "sl": 4170.0, "tp": 4190.0, "magic": 123456, "comment": "test", "deviation": 10 } }) print(resp.json()) ``` ### curl ```bash # 健康检查 curl -H "X-API-Key: 你的密码" http://IP:端口/health # 账户信息 curl -H "X-API-Key: 你的密码" http://IP:端口/account # 下单 curl -X POST http://IP:端口/order/send \ -H "Content-Type: application/json" \ -H "X-API-Key: 你的密码" \ -d '{"request":{"action":1,"symbol":"XAUUSDc","volume":0.01,"order_type":0,"price":4180.0,"sl":4170.0,"tp":4190.0,"magic":123456,"comment":"test","deviation":10}}' ``` --- ## 八、迁移到新主机 ### 需要复制的内容 | 从哪里 | 复制什么 | 放到哪里 | |--------|---------|---------| | 本地 `bin\Debug\net8.0\` | 整个文件夹 | 新主机 `C:\Mt5Bridge\` | | MtApi5 安装包 | 运行 MSI 安装 | 新主机 | | MtApi5 项目 | `MtApi5.ex5` | 新主机 MT5 的 `MQL5\Experts\` | ### 新主机操作步骤 1. 安装 .NET 8 ASP.NET Core Runtime 2. 运行 MtApi5 MSI 安装包 3. 复制 `bin\Debug\net8.0\` 到 `C:\Mt5Bridge\` 4. 复制 `MtApi5.ex5` 到 MT5 Experts 目录 5. 在 MT5 图表上挂载 MtApi5 EA 6. 配置云服务商端口映射(如需要外网访问) 7. 配置 Windows 防火墙 8. 注册任务计划程序实现开机自启 9. 验证:`Invoke-RestMethod -Uri "http://localhost:8080/health" -Headers @{"X-API-Key"="密码"}` --- ## 九、常用维护命令 ```powershell # 查看 Bridge 是否在运行 Get-ScheduledTask -TaskName "Mt5Bridge" | Get-ScheduledTaskInfo # 查看是否在监听端口 netstat -ano | findstr 8080 # 查看 .NET 运行时版本 dotnet --list-runtimes # 手动启动 Bridge(前台调试) cd C:\Mt5Bridge dotnet Mt5Bridge.dll # 杀死 Bridge 进程 Stop-ScheduledTask -TaskName "Mt5Bridge" ``` --- ## 十、安全建议 1. **API Key 必须修改**:部署前把默认的 `mt5bridge-2024-secret-key` 改成随机字符串 2. **端口号不要用默认的**:使用 13485-13489 范围内的随机端口 3. **防火墙白名单**:如果只有固定 IP 访问,在云服务商安全组里限制来源 IP 4. **不要用 HTTP 明文传输敏感数据**:可配合 Nginx Proxy Manager 加 HTTPS 5. **定期更换 API Key**:修改 `Program.cs` 中的 Key 后重新编译部署