Files
my-Mt5Bridge/README.md.md
T

582 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 RuntimeWindows 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 后重新编译部署