414 lines
11 KiB
Markdown
414 lines
11 KiB
Markdown
# Mt5Bridge — MT5 HTTP API 网关
|
||||
|
|
|
|||
|
|
通过 HTTP REST 接口操控 MetaTrader 5,零依赖、可独立部署。
|
|||
|
|
|
|||
|
|
## 架构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
任何语言的项目 (Rust / Python / Node / Go / ...)
|
|||
|
|
│
|
|||
|
|
▼ HTTP REST API (localhost:8080)
|
|||
|
|
│
|
|||
|
|
Mt5Bridge (C# + MtApi5)
|
|||
|
|
│
|
|||
|
|
▼ localhost:8228
|
|||
|
|
MtApi5 EA (MT5 图表上运行)
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
MetaTrader 5 客户端
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 快速开始
|
|||
|
|
|
|||
|
|
### 前置条件
|
|||
|
|
|
|||
|
|
| 依赖 | 说明 |
|
|||
|
|
| ------------------- | ------------------------------------------------------- |
|
|||
|
|
| .NET 8 SDK | 编译运行 |
|
|||
|
|
| MetaTrader 5 客户端 | 已登录任意账户 |
|
|||
|
|
| MtApi5 EA | 挂载在 MT5 任意图表上,默认监听端口 8228 |
|
|||
|
|
| MtApi5 已安装 | `C:\Program Files\MtApi5\`(本项目 `libs/` 下已有 DLL) |
|
|||
|
|
|
|||
|
|
### 启动
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd Mt5Bridge
|
|||
|
|
dotnet run
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
看到以下输出即启动成功:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
info: MtConnectionService[0]
|
|||
|
|
Connecting to MT5 via MtApi5 on port 8228...
|
|||
|
|
info: MtConnectionService[0]
|
|||
|
|
MT5 Connection: Connected
|
|||
|
|
info: MtConnectionService[0]
|
|||
|
|
MT5 Bridge ready on http://localhost:8080
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 健康检查
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
curl http://localhost:8080/health
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
响应示例:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"status": "healthy",
|
|||
|
|
"mt5_connected": true,
|
|||
|
|
"mt5_version": "unknown",
|
|||
|
|
"api_version": "1.0.0"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## API 接口
|
|||
|
|
|
|||
|
|
### 账户
|
|||
|
|
|
|||
|
|
#### `GET /health`
|
|||
|
|
|
|||
|
|
健康检查,返回 MT5 连接状态。
|
|||
|
|
|
|||
|
|
#### `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}`
|
|||
|
|
|
|||
|
|
获取品种详细信息。
|
|||
|
|
|
|||
|
|
**示例:** `GET /symbols/XAUUSDc`
|
|||
|
|
|
|||
|
|
**响应字段:**
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 说明 |
|
|||
|
|
| ------------------- | ------ | ------------ |
|
|||
|
|
| name | string | 品种名 |
|
|||
|
|
| description | string | 描述 |
|
|||
|
|
| digits | int | 小数位数 |
|
|||
|
|
| point | double | 点值 |
|
|||
|
|
| spread | int | 点差 |
|
|||
|
|
| spread_float | bool | 是否浮动点差 |
|
|||
|
|
| bid | double | 卖价 |
|
|||
|
|
| ask | double | 买价 |
|
|||
|
|
| volume_min | double | 最小手数 |
|
|||
|
|
| volume_max | double | 最大手数 |
|
|||
|
|
| volume_step | double | 手数步长 |
|
|||
|
|
| trade_contract_size | double | 合约大小 |
|
|||
|
|
| currency_base | string | 基础货币 |
|
|||
|
|
| currency_profit | string | 盈亏货币 |
|
|||
|
|
| category | string | 品种路径 |
|
|||
|
|
|
|||
|
|
#### `GET /symbols/{symbol}/tick`
|
|||
|
|
|
|||
|
|
获取品种最新报价。
|
|||
|
|
|
|||
|
|
**响应字段:**
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 说明 |
|
|||
|
|
| ----------- | ------ | ------------------- |
|
|||
|
|
| time | string | 报价时间 (ISO 8601) |
|
|||
|
|
| bid | double | 卖价 |
|
|||
|
|
| ask | double | 买价 |
|
|||
|
|
| last | double | 最新成交价 |
|
|||
|
|
| volume | double | 成交量 |
|
|||
|
|
| volume_real | double | 真实成交量 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 行情数据
|
|||
|
|
|
|||
|
|
#### `GET /rates/from-pos`
|
|||
|
|
|
|||
|
|
从指定位置获取历史 K 线。
|
|||
|
|
|
|||
|
|
**参数:**
|
|||
|
|
|
|||
|
|
| 参数 | 类型 | 说明 |
|
|||
|
|
| --------- | ------ | ----------------------- |
|
|||
|
|
| symbol | string | 品种名 |
|
|||
|
|
| timeframe | string | 周期,如 `TIMEFRAME_M5` |
|
|||
|
|
| start_pos | int | 起始位置(0 为最新) |
|
|||
|
|
| count | int | 获取数量 |
|
|||
|
|
|
|||
|
|
**支持的周期:**
|
|||
|
|
|
|||
|
|
| 值 | 含义 |
|
|||
|
|
| --------------- | ------- |
|
|||
|
|
| `TIMEFRAME_M1` | 1 分钟 |
|
|||
|
|
| `TIMEFRAME_M5` | 5 分钟 |
|
|||
|
|
| `TIMEFRAME_M15` | 15 分钟 |
|
|||
|
|
| `TIMEFRAME_M30` | 30 分钟 |
|
|||
|
|
| `TIMEFRAME_H1` | 1 小时 |
|
|||
|
|
| `TIMEFRAME_H4` | 4 小时 |
|
|||
|
|
| `TIMEFRAME_D1` | 日线 |
|
|||
|
|
|
|||
|
|
**响应:** 每根 K 线包含 `time`, `open`, `high`, `low`, `close`, `tick_volume`, `spread`, `real_volume`。
|
|||
|
|
|
|||
|
|
> 单次请求最大 50000 根,内部自动分批(每批 1000 根)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 持仓
|
|||
|
|
|
|||
|
|
#### `GET /positions`
|
|||
|
|
|
|||
|
|
获取当前所有持仓。
|
|||
|
|
|
|||
|
|
**响应字段:**
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 说明 |
|
|||
|
|
| ------------- | ------ | ------------- |
|
|||
|
|
| ticket | number | 持仓号 |
|
|||
|
|
| symbol | string | 品种 |
|
|||
|
|
| type | int | 0=Buy, 1=Sell |
|
|||
|
|
| volume | double | 手数 |
|
|||
|
|
| price_open | double | 开仓价 |
|
|||
|
|
| sl | double | 止损 |
|
|||
|
|
| tp | double | 止盈 |
|
|||
|
|
| price_current | double | 当前价 |
|
|||
|
|
| swap | double | 库存费 |
|
|||
|
|
| profit | double | 浮动盈亏 |
|
|||
|
|
| comment | string | 注释 |
|
|||
|
|
| magic | number | Magic Number |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 挂单
|
|||
|
|
|
|||
|
|
#### `GET /orders?symbol={symbol}`
|
|||
|
|
|
|||
|
|
获取挂单列表。可选参数 `symbol` 过滤品种。
|
|||
|
|
|
|||
|
|
**响应字段:**
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 说明 |
|
|||
|
|
| -------------- | ------ | ------------ |
|
|||
|
|
| ticket | number | 订单号 |
|
|||
|
|
| symbol | string | 品种 |
|
|||
|
|
| type | int | 订单类型 |
|
|||
|
|
| volume_initial | double | 原始手数 |
|
|||
|
|
| price_open | double | 挂单价 |
|
|||
|
|
| sl | double | 止损 |
|
|||
|
|
| tp | double | 止盈 |
|
|||
|
|
| magic | number | Magic Number |
|
|||
|
|
| comment | string | 注释 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 交易
|
|||
|
|
|
|||
|
|
#### `POST /order/check`
|
|||
|
|
|
|||
|
|
校验订单参数(不实际下单),检查保证金是否足够。
|
|||
|
|
|
|||
|
|
**请求体:**
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"action": 1,
|
|||
|
|
"symbol": "XAUUSDc",
|
|||
|
|
"volume": 0.01,
|
|||
|
|
"order_type": 0,
|
|||
|
|
"price": 4170.50,
|
|||
|
|
"sl": 4168.00,
|
|||
|
|
"tp": 4175.00,
|
|||
|
|
"magic": 12345,
|
|||
|
|
"comment": "test"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**action 取值:**
|
|||
|
|
|
|||
|
|
| 值 | 含义 |
|
|||
|
|
| ---- | -------- |
|
|||
|
|
| 1 | 市价单 |
|
|||
|
|
| 6 | 限价挂单 |
|
|||
|
|
|
|||
|
|
**order_type 取值:**
|
|||
|
|
|
|||
|
|
| 值 | 含义 |
|
|||
|
|
| ---- | ---------- |
|
|||
|
|
| 0 | Buy |
|
|||
|
|
| 1 | Sell |
|
|||
|
|
| 2 | Buy Limit |
|
|||
|
|
| 3 | Sell Limit |
|
|||
|
|
| 4 | Buy Stop |
|
|||
|
|
| 5 | Sell Stop |
|
|||
|
|
|
|||
|
|
**响应字段:**
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 说明 |
|
|||
|
|
| ----------- | ------ | ------------------ |
|
|||
|
|
| retcode | uint | 返回码,0 表示成功 |
|
|||
|
|
| balance | double | 模拟下单后余额 |
|
|||
|
|
| equity | double | 净值 |
|
|||
|
|
| margin | double | 所需保证金 |
|
|||
|
|
| margin_free | double | 可用保证金 |
|
|||
|
|
| comment | string | 错误描述 |
|
|||
|
|
|
|||
|
|
#### `POST /order/send`
|
|||
|
|
|
|||
|
|
实际下单/改单/平仓。
|
|||
|
|
|
|||
|
|
**请求体(嵌套结构):**
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"request": {
|
|||
|
|
"action": 6,
|
|||
|
|
"symbol": "XAUUSDc",
|
|||
|
|
"volume": 0.01,
|
|||
|
|
"order_type": 2,
|
|||
|
|
"price": 4165.00,
|
|||
|
|
"sl": 4160.00,
|
|||
|
|
"tp": 4175.00,
|
|||
|
|
"magic": 12345,
|
|||
|
|
"comment": "my_bot",
|
|||
|
|
"order": 0,
|
|||
|
|
"position": 0,
|
|||
|
|
"deviation": 10
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**字段说明:**
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 说明 |
|
|||
|
|
| ---------- | ------ | -------------------------- |
|
|||
|
|
| action | uint | 参考上表 |
|
|||
|
|
| symbol | string | 品种 |
|
|||
|
|
| volume | double | 手数 |
|
|||
|
|
| order_type | uint | 订单类型 |
|
|||
|
|
| price | double | 价格(市价单可不填) |
|
|||
|
|
| sl | double | 止损价 |
|
|||
|
|
| tp | double | 止盈价 |
|
|||
|
|
| magic | ulong | 自定义标识 |
|
|||
|
|
| comment | string | 注释 |
|
|||
|
|
| order | ulong | 要修改的订单号(改单时用) |
|
|||
|
|
| position | ulong | 要平仓的持仓号(平仓时用) |
|
|||
|
|
| deviation | ulong | 最大滑点 |
|
|||
|
|
|
|||
|
|
**修改订单:** 设置 `order` 为目标订单号,只需传要修改的字段。
|
|||
|
|
|
|||
|
|
**平仓:** 设置 `position` 为持仓号,`action=1`,`order_type` 与持仓方向相反。
|
|||
|
|
|
|||
|
|
**响应字段:**
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 说明 |
|
|||
|
|
| ------- | ------ | ------------------------ |
|
|||
|
|
| retcode | uint | 返回码,`10009` 表示成功 |
|
|||
|
|
| order | ulong | 成交/挂单号 |
|
|||
|
|
| comment | string | 服务器返回信息 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 历史记录
|
|||
|
|
|
|||
|
|
#### `GET /history/deals`
|
|||
|
|
|
|||
|
|
查询历史成交记录。
|
|||
|
|
|
|||
|
|
**参数:**
|
|||
|
|
|
|||
|
|
| 参数 | 类型 | 说明 |
|
|||
|
|
| --------- | ------ | --------------------- |
|
|||
|
|
| date_from | string | 起始日期 `yyyy-MM-dd` |
|
|||
|
|
| date_to | string | 结束日期 `yyyy-MM-dd` |
|
|||
|
|
| symbol | string | 可选,过滤品种 |
|
|||
|
|
|
|||
|
|
**响应字段:**
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 说明 |
|
|||
|
|
| ---------- | ------ | ------------ |
|
|||
|
|
| ticket | number | 成交号 |
|
|||
|
|
| time | string | 成交时间 |
|
|||
|
|
| entry | int | 0=In, 1=Out |
|
|||
|
|
| magic | number | Magic Number |
|
|||
|
|
| volume | double | 手数 |
|
|||
|
|
| price | double | 成交价 |
|
|||
|
|
| profit | double | 盈亏 |
|
|||
|
|
| commission | double | 佣金 |
|
|||
|
|
| swap | double | 库存费 |
|
|||
|
|
| symbol | string | 品种 |
|
|||
|
|
| comment | string | 注释 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 项目结构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Mt5Bridge/
|
|||
|
|
├── Program.cs # 全部代码(单文件 ASP.NET Core)
|
|||
|
|
├── Mt5Bridge.csproj # 项目文件
|
|||
|
|
├── libs/ # MtApi5 依赖 DLL
|
|||
|
|
│ ├── MtApi5.dll
|
|||
|
|
│ ├── MtClient.dll
|
|||
|
|
│ └── Newtonsoft.Json.dll
|
|||
|
|
└── README.md
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 部署到其他机器
|
|||
|
|
|
|||
|
|
1. 拷贝整个 `Mt5Bridge/` 文件夹
|
|||
|
|
2. 确保目标机器安装了 .NET 8 SDK
|
|||
|
|
3. 确保 MT5 客户端已登录 + MtApi5 EA 挂载在图表上
|
|||
|
|
4. `dotnet run` 即可启动
|
|||
|
|
|
|||
|
|
## 修改端口
|
|||
|
|
|
|||
|
|
编辑 `Program.cs` 第 5 行:
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
builder.WebHost.UseUrls("http://localhost:8080");
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
将 `8080` 改为其他端口即可。
|
|||
|
|
|
|||
|
|
## 连接超时
|
|||
|
|
|
|||
|
|
当前 CommandTimeout 设为 120 秒(通过反射设置),适用于请求大量历史 K 线的场景。如需调整,修改 `Program.cs` 第 14 行即可。
|
|||
|
|
|
|||
|
|
## 常见问题
|
|||
|
|
|
|||
|
|
**Q: 启动后一直显示 "Connecting..."?**
|
|||
|
|
|
|||
|
|
A: 确保 MT5 已打开并登录,且 MtApi5 EA 已挂载在任意图表上。EA 默认监听 8228 端口。
|
|||
|
|
|
|||
|
|
**Q: 请求返回 500 错误?**
|
|||
|
|
|
|||
|
|
A: 查看 Bridge 控制台输出的错误日志,常见原因:品种名不存在、MT5 断连、数据量过大超时。
|
|||
|
|
|
|||
|
|
**Q: 能用在其他语言的项目中吗?**
|
|||
|
|
|
|||
|
|
A: 可以。Bridge 是标准 HTTP REST API,任何语言的 HTTP 客户端都能调用。详见上方 API 文档。
|
|||
|
|
|