Files
NewStock/qmt/qmt_functionality.md
liaozhaorun 7b4112b70b efactor(qmt): 重构架构 - 统一信号发送和消息处理
- 修复 qmt_engine.py 中 initialize() 的重复代码
- 新增 message_processor.py: Redis Stream 消息处理器
- 新增 logger.py: 细粒度日志模块
- 新增 qmt_sender.py: 统一信号发送端(槽位+百分比模式)
- 新增 backtest_consumer.py: 回测消息消费者
- 删除旧模块: qmt_trader.py, qmt_signal_sender.py, qmt_percentage_sender.py
- 更新文档: qmt_functionality.md 反映新架构
2026-02-25 20:49:56 +08:00

619 lines
29 KiB
Markdown
Raw Permalink 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.
# QMT 模块功能文档
## 1. 系统概述
QMT 模块是 NewStock 量化交易系统的实盘交易执行模块,通过 `xtquant` 库连接 QMT 交易终端,实现自动化交易功能。该模块采用多终端架构设计,支持同时管理多个 QMT 终端实例,并提供 Web 仪表盘和 RESTful API 接口进行监控和操作。
系统核心特性包括:多终端并行管理、异步订单处理、断线自动重连、收盘自动清算、实时心跳检测等。所有交易信号通过 Redis Stream 消息队列接收,确保交易指令的可靠传递和执行。
系统分为**信号发送端**和**交易执行端**两部分。信号发送端(`qmt_sender.py`)运行在聚宽策略环境中,将策略产生的买卖信号推送至 Redis Stream交易执行端`qmt_engine.py` + `run.py`)运行在本地,从 Redis Stream 消费信号并通过 QMT 终端执行实盘交易。
## 2. 核心组件
### 2.1 文件结构
| 文件 | 说明 |
|------|------|
| [`run.py`](run.py) | 系统启动入口,负责初始化多终端管理器并启动 API 服务 |
| [`qmt_engine.py`](qmt_engine.py) | 核心引擎模块,包含多终端管理器和交易执行单元 |
| [`qmt_sender.py`](qmt_sender.py) | 统一信号发送端,支持槽位模式和百分比模式,运行于聚宽策略侧 |
| [`backtest_consumer.py`](backtest_consumer.py) | 回测消息消费者,模拟交易执行并记录完整日志 |
| [`message_processor.py`](message_processor.py) | Redis Stream 消息处理器,封装消息发送、消费、确认等功能 |
| [`logger.py`](logger.py) | 细粒度日志模块,追踪消息处理全流程 |
| [`api_server.py`](api_server.py) | FastAPI Web 服务,提供 RESTful API 接口 |
| [`dashboard.html`](dashboard.html) | Web 仪表盘前端页面 |
| [`start.bat`](start.bat) | Windows 启动脚本 |
| [`logs/`](logs/) | 系统运行日志目录 |
### 2.2 核心类说明
#### qmt_engine.py
| 类名 | 功能说明 |
|------|----------|
| `MultiEngineManager` | 多终端管理器单例,负责管理所有 QMT 终端实例和交易路由 |
| `TradingUnit` | 终端执行单元,代表单个 QMT 进程的管理器 |
| `PositionManager` | Redis 虚拟持仓管理器,维护策略级别的持仓状态 |
| `DailySettlement` | 日终对账处理器,执行收盘后的持仓核对 |
| `AutoReconnectScheduler` | 定时自动重连调度器,支持配置重连时间和启用状态 |
| `UnitCallback` | 终端回调处理器,处理成交回报和错误通知 |
| `TerminalStatus` | 终端状态数据类,封装终端连接状态信息 |
#### qmt_sender.py
| 函数 | 功能说明 |
|------|----------|
| `send_qmt_signal()` | 发送槽位模式信号(基于 total_slots |
| `send_qmt_percentage_signal()` | 发送百分比模式信号(基于 position_pct |
#### backtest_consumer.py
| 类名 | 功能说明 |
|------|----------|
| `BacktestConsumer` | 回测消息消费者,支持守护模式和单次运行模式 |
#### message_processor.py
| 类名 | 功能说明 |
|------|----------|
| `StreamMessageProcessor` | Redis Stream 消息处理器,支持消息发送、消费、确认、失败处理 |
#### logger.py
| 类名 | 功能说明 |
|------|----------|
| `QMTLogger` | 细粒度日志记录器,追踪消息接收、解析、校验、执行、确认全流程 |
## 3. 功能详细说明
### 3.1 多终端管理
系统支持同时连接和管理多个 QMT 终端实例,每个终端可以配置独立的账户信息。每个 `TradingUnit` 对应一个 QMT 终端,具备独立的连接状态、回调处理和交易能力。终端之间相互隔离,可以通过配置文件定义每个策略使用哪个终端执行交易。
多终端管理器的核心职责包括:终端初始化、连接状态监控、健康检查、断线重连、交易消息路由等。主循环每 25 秒执行一次健康检查,通过查询资产验证物理连接有效性。当检测到连接丢失时,系统自动执行重连操作,并避开 QMT 夜间重启高峰期。
### 3.2 交易消息处理
交易信号通过 Redis Stream 消息队列传递,每个策略对应一个独立的 Stream。消息格式为 JSON 对象,包含股票代码、操作类型、价格、时间戳等字段。系统对每条消息进行严格校验,包括日期校验、时间戳校验、必填字段校验等,确保只有当天的有效指令才会被执行。
买入逻辑支持两种模式:
1. **槽位控制模式**:通过 `total_slots` 参数限制同时持有的股票数量。系统根据可用资金和目标槽位自动计算每只股票的买入数量,金额过小或股数不足的请求会被拦截。
2. **仓位百分比模式**:通过 `position_pct` 参数指定目标持仓占账户总资产的比例。系统根据账户总资产计算目标金额,然后转换为具体股数进行下单。该模式无持仓数量限制。
卖出逻辑根据策略配置模式有所不同:槽位模式下根据 Redis 中的虚拟持仓和实盘可用持仓计算实际卖出数量;百分比模式下执行清仓操作。
### 3.3 持仓管理
持仓管理采用虚拟账本与实盘持仓双轨制。虚拟账本记录策略意图持有的股票,通过 Redis Hash 结构存储,使用 `POS:{strategy_name}` 作为键。当策略发出买入指令时,系统先在虚拟账本中标记持仓,再执行实际委托。
成交回调会实时更新虚拟持仓数量,买入增加持仓,卖出减少持仓。如果下单失败,系统会自动回滚虚拟持仓的槽位占用。日终结算时会核对虚拟持仓与实盘持仓的差异,发现幽灵持仓或占位符不一致时自动修正。
### 3.4 断线重连机制
系统实现了三级断线检测和自动重连机制。第一级是回调通知,当 QMT 底层检测到连接断开时触发 `on_disconnected` 回调。第二级是逻辑状态跟踪,系统维护 `callback.is_connected` 标志反映回调状态。第三级是物理探测,通过查询账户资产验证连接是否真正有效。
重连策略包含智能避让机制,在每日 21:32 至 21:50 的 QMT 维护时段内不执行重连操作,避免与系统重启冲突。自动重连调度器支持配置定时执行重连任务,可在盘后 22:00 自动断开并重新建立所有连接。
### 3.5 日终清算
日终清算是系统的重要保障机制,在每个交易日收盘后自动执行。清算流程包括三个步骤:首先撤销所有可撤单订单,释放未成交的委托;然后查询实盘真实持仓,建立持仓映射;最后遍历所有策略的虚拟持仓,与实盘进行比对和修正。
清算过程中发现的异常情况包括幽灵持仓Redis 有记录但实盘无持仓和占位符不一致Redis 记录为 0 但实盘有持仓)。这些异常会被自动修正,确保系统状态与实际账户一致。清算完成后设置标志位,防止重复执行。
### 3.6 日志系统
系统采用增强型日志系统,支持文件和控制台双路输出。日志格式包含时间戳、线程名、级别和消息内容,便于追踪问题。文件日志按日期命名,自动存放在 `logs/` 目录下。控制台输出强制刷新流,确保在 Windows 环境下日志实时显示。
新增 `logger.py` 模块提供细粒度日志记录,追踪消息处理全流程:
- 消息接收(`log_message_receive`
- 消息解析(`log_message_parse`
- 业务校验(`log_validation`
- 订单执行(`log_order_execution`
- 消息确认(`log_message_ack`
- 失败处理(`log_failure`
## 4. API 接口列表
### 4.1 端点列表
| 方法 | 路径 | 功能说明 |
|------|------|----------|
| GET | `/` | 返回 Web 仪表盘页面 |
| GET | [`/api/status`](api_server.py:154) | 获取所有终端的连接状态 |
| GET | [`/api/positions`](api_server.py:177) | 获取实盘持仓和虚拟持仓 |
| GET | [`/api/logs`](api_server.py:234) | 获取系统运行日志 |
| GET | [`/api/health`](api_server.py:240) | 健康检查接口 |
| GET | [`/api/config`](api_server.py:251) | 获取自动重连配置 |
| POST | [`/api/config`](api_server.py:260) | 更新自动重连配置 |
| POST | [`/api/reconnect`](api_server.py:279) | 手动触发所有终端重连 |
| GET | [`/api/file_config`](api_server.py:288) | 获取配置文件内容(敏感信息脱敏) |
### 4.2 响应模型
#### StatusResponse
```json
{
"running": true,
"start_time": "2026-01-27 10:00:00",
"terminals": [
{
"qmt_id": "terminal_001",
"alias": "主账户",
"account_id": "****1234",
"is_connected": true,
"callback_connected": true,
"physical_connected": true,
"last_heartbeat": "10:30:15"
}
]
}
```
#### PositionsResponse
```json
{
"real_positions": {
"terminal_001": [
{"code": "600519", "volume": 1000, "can_use": 500, "market_value": 850000.00}
]
},
"virtual_positions": {
"strategy_a": {"600519": "500", "000001": "1000"}
}
}
```
#### ConfigResponse
```json
{
"reconnect_time": "22:00",
"auto_reconnect_enabled": true
}
```
## 5. 配置说明
### 5.1 配置文件结构
系统使用 `config.json` 作为主配置文件,文件结构如下:
```json
{
"redis": {
"host": "localhost",
"port": 6379,
"db": 0,
"password": null
},
"qmt_terminals": [
{
"qmt_id": "terminal_001",
"alias": "主账户",
"path": "C:/QMT/xiadan/",
"account_id": "12345678",
"account_type": "STOCK"
}
],
"strategies": {
"strategy_a": {
"qmt_id": "terminal_001",
"total_slots": 5,
"execution": {
"buy_amount_per_stock": 20000,
"min_buy_amount": 2000
}
}
},
"auto_reconnect": {
"enabled": true,
"reconnect_time": "22:00"
}
}
```
### 5.2 配置项说明
| 配置项 | 类型 | 说明 |
|--------|------|------|
| `redis` | Object | Redis 连接配置,支持 host、port、db、password 等参数 |
| `qmt_terminals` | Array | QMT 终端列表,每个终端包含唯一标识、别名、路径、账户信息 |
| `strategies` | Object | 策略配置,键为策略名,值包含使用的终端 ID 和执行参数 |
| `total_slots` | Integer | 策略的最大持仓股票数量(槽位模式) |
| `order_mode` | String | 下单模式,可选 `slots`(槽位)或 `percentage`(百分比),默认为 `slots` |
| `auto_reconnect` | Object | 自动重连配置,包含启用状态和执行时间 |
**槽位模式配置示例:**
```json
{
"strategies": {
"strategy_a": {
"qmt_id": "terminal_001",
"order_mode": "slots",
"total_slots": 5,
"execution": {
"buy_amount_per_stock": 20000,
"min_buy_amount": 2000
}
}
}
}
```
**百分比模式配置示例:**
```json
{
"strategies": {
"strategy_b": {
"qmt_id": "terminal_001",
"order_mode": "percentage"
}
}
}
```
### 5.3 环境变量配置
系统支持通过 `.env.local` 文件或环境变量配置以下参数:
| 变量名 | 默认值 | 说明 |
|--------|--------|------|
| `REDIS_HOST` | localhost | Redis 主机地址 |
| `REDIS_PORT` | 6379 | Redis 端口 |
| `REDIS_PASSWORD` | None | Redis 密码 |
| `REDIS_DB` | 0 | Redis 数据库 |
| `BACKTEST_CONSUMER_ID` | backtest-consumer-1 | 回测消费者 ID |
| `BACKTEST_STRATEGIES` | "" | 默认策略列表,逗号分隔 |
| `LOG_LEVEL` | DEBUG | 日志级别 |
| `LOG_FILE` | logs/backtest_consumer.log | 日志文件路径 |
## 6. Web 仪表盘功能
### 6.1 功能概览
Web 仪表盘基于 Vue 3 和 Naive UI 组件库开发,提供可视化的系统监控界面。仪表盘支持暗黑主题,采用卡片式布局展示各类信息。页面每 30 秒自动刷新,也支持手动点击刷新按钮获取最新数据。
### 6.2 功能模块
| 模块 | 功能说明 |
|------|----------|
| 顶部状态栏 | 显示系统运行状态总览,提供配置查看、重连、刷新按钮 |
| 终端状态卡片 | 展示每个 QMT 终端的连接状态、账户信息、心跳时间 |
| 持仓统计卡片 | 显示持仓品种数、总持仓量、总市值、策略数 |
| 实盘持仓面板 | 按终端分组展示真实持仓,包含代码、持仓量、可用量、市值 |
| 虚拟账本面板 | 按策略分组展示 Redis 持仓记录 |
| 系统日志面板 | 实时滚动显示系统运行日志,按级别着色 |
| 配置查看模态框 | 展示 Redis 配置、终端配置、策略配置,支持复制 JSON 源码 |
### 6.3 访问地址
仪表盘默认访问地址为 `http://localhost:8001`,该地址在系统启动时打印在控制台。首次访问时会自动加载所有终端状态、持仓信息和系统日志。
## 7. 信号发送端qmt_sender.py
### 7.1 模块定位
`qmt_sender.py` 是 QMT 交易系统的**信号生产端**部署在聚宽JoinQuant策略运行环境中。它负责将策略产生的买卖信号序列化后推送到 Redis Stream由本地 QMT 交易引擎消费并执行。该模块是连接"策略研究/回测平台"与"实盘交易执行"的桥梁。
该模块统一了槽位模式和百分比模式,通过不同函数发送不同类型的信号。
### 7.2 核心函数
#### `send_qmt_signal(code, target_total_slots, price, context, redis_config)`
发送槽位模式信号。
| 参数 | 类型 | 说明 |
|------|------|------|
| `code` | str | 股票代码,聚宽格式(如 `000001.XSHE``600519.XSHG` |
| `target_total_slots` | int | 目标总槽位数。大于 0 表示买入意图,等于 0 表示卖出(清仓)意图 |
| `price` | float | 当前最新价格,用于实盘限价单参考 |
| `context` | object | 聚宽上下文对象,提供 `run_params.type`(运行类型)和 `current_dt`(当前时间) |
| `redis_config` | dict | Redis 连接配置,包含 `host``port``password``db``strategy_name` 等字段 |
#### `send_qmt_percentage_signal(code, position_pct, action, price, is_backtest, timestamp, redis_config)`
发送百分比模式信号。
| 参数 | 类型 | 说明 |
|------|------|------|
| `code` | str | 股票代码,聚宽格式(如 `000001.XSHE``600519.XSHG` |
| `position_pct` | float | 目标持仓占总资产的比例,范围 0.0 ~ 1.0(如 0.2 表示 20% |
| `action` | str | 交易动作,固定为 `"BUY"``"SELL"` |
| `price` | float | 当前最新价格,用于实盘限价单参考 |
| `is_backtest` | bool | 是否为回测模式True/False |
| `timestamp` | str | 时间戳字符串,格式 `"YYYY-MM-DD HH:MM:SS"` |
| `redis_config` | dict | Redis 连接配置,包含 `host``port``password``db``strategy_name` 等字段 |
### 7.3 处理流程
```
策略触发信号
1. 环境判断与流量控制
├─ 实盘模式 → 直接通过
└─ 回测模式 → 限制最多发送 10 条(防止回测刷爆队列)
2. 建立 Redis Stream 连接
3. 数据转换与规范化
├─ 股票代码格式转换:.XSHE → .SZ.XSHG → .SH
└─ 动作判定槽位模式target_total_slots > 0 → BUY= 0 → SELL
4. 构建 JSON 消息体
5. Stream 路由
├─ 回测 → qmt:{strategy_name}:backtest
└─ 实盘 → qmt:{strategy_name}:real
6. 控制台日志输出
```
### 7.4 消息格式
发送到 Redis Stream 的 JSON 消息结构:
**槽位模式:**
```json
{
"strategy_name": "my_strategy",
"stock_code": "000001.SZ",
"action": "BUY",
"price": 15.50,
"total_slots": 5,
"timestamp": "2026-02-17 14:30:00",
"is_backtest": false
}
```
**百分比模式:**
```json
{
"strategy_name": "my_strategy",
"stock_code": "000001.SZ",
"action": "BUY",
"price": 15.50,
"position_pct": 0.2,
"timestamp": "2026-02-17 14:30:00",
"is_backtest": false
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| `strategy_name` | str | 策略名称,来自 `redis_config['strategy_name']`,用于队列路由和持仓管理 |
| `stock_code` | str | QMT 格式的股票代码(`.SZ` / `.SH` |
| `action` | str | 交易动作,`BUY``SELL` |
| `price` | float | 信号触发时的最新价格 |
| `total_slots` | int | 策略的总槽位数(槽位模式) |
| `position_pct` | float | 目标持仓占账户总资产的比例(百分比模式) |
| `timestamp` | str | 信号生成时间,格式 `YYYY-MM-DD HH:MM:SS` |
| `is_backtest` | bool | 是否为回测环境发出的信号 |
### 7.5 买卖意图判定逻辑
**槽位模式**:通过 `target_total_slots` 参数的值进行语义推断:
- **`target_total_slots > 0`**BUY策略意向持有该股票`total_slots` 传递策略的总持仓上限,供交易引擎计算单只股票的资金分配。
- **`target_total_slots = 0`**SELL策略意向清仓该股票释放所占槽位。
**百分比模式**:需要**显式指定**交易动作:
- **`action = "BUY"`**:策略意向买入该股票,目标持仓占比为 `position_pct`。交易引擎根据账户总资产计算目标金额,然后转换为具体股数下单。
- **`action = "SELL"`**:策略意向清仓该股票。百分比模式下卖出采用简化逻辑,直接执行清仓操作。
### 7.6 回测流量控制
模块级全局变量 `_BACKTEST_SEND_COUNT` 用于限制回测模式下的信号发送数量,上限为 10 条。这一机制防止长周期回测期间大量无效信号涌入 Redis 队列。
### 7.7 Stream 命名规则
| 运行模式 | Stream 键名格式 |
|----------|----------------|
| 实盘 | `qmt:{strategy_name}:real` |
| 回测 | `qmt:{strategy_name}:backtest` |
### 7.8 股票代码格式转换
| 来源平台 | 格式 | 示例 |
|----------|------|------|
| 聚宽 | `.XSHE` / `.XSHG` | `000001.XSHE``600519.XSHG` |
| QMT | `.SZ` / `.SH` | `000001.SZ``600519.SH` |
### 7.9 使用示例
```python
from qmt_sender import send_qmt_signal, send_qmt_percentage_signal
# Redis 配置
redis_config = {
"host": "localhost",
"port": 6379,
"password": None,
"db": 0,
"strategy_name": "MyStrategy"
}
# 槽位模式买入信号
send_qmt_signal(
code="000001.XSHE",
target_total_slots=5,
price=15.5,
context=context, # 聚宽上下文
redis_config=redis_config
)
# 百分比模式买入信号(目标持仓 20%
send_qmt_percentage_signal(
code="000001.XSHE",
position_pct=0.2,
action="BUY",
price=15.5,
is_backtest=False,
timestamp="2026-02-17 14:30:00",
redis_config=redis_config
)
```
## 8. 回测消息消费者backtest_consumer.py
### 8.1 模块定位
`backtest_consumer.py` 是独立的回测消息消费脚本,用于消费回测消息流、记录完整的处理流程日志、模拟订单执行(不执行真实交易),并支持 ACK 确认消息。
### 8.2 使用方式
```bash
# 守护模式(持续运行,处理所有配置的策略)
python backtest_consumer.py
# 单次运行模式(处理一次后退出)
python backtest_consumer.py --once
# 指定策略运行
python backtest_consumer.py --strategy StrategyA
python backtest_consumer.py --once --strategy StrategyA,StrategyB
```
### 8.3 配置说明
可通过环境变量或 `.env.local` 文件配置:
- `REDIS_HOST`: Redis 主机地址(默认: localhost
- `REDIS_PORT`: Redis 端口(默认: 6379
- `REDIS_PASSWORD`: Redis 密码(默认: None
- `REDIS_DB`: Redis 数据库(默认: 0
- `BACKTEST_CONSUMER_ID`: 消费者ID默认: backtest-consumer-1
- `BACKTEST_STRATEGIES`: 默认策略列表,逗号分隔
- `LOG_LEVEL`: 日志级别(默认: DEBUG
- `LOG_FILE`: 日志文件路径(默认: logs/backtest_consumer.log
## 9. 系统架构
### 9.1 组件关系图
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ QMT 交易系统架构 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────────┐ ┌─────────────────────────┐ │
│ │ 启动入口 │ │ 多终端管理器 │ │ API 服务器 │ │
│ │ run.py │ ──> │ MultiEngineMgr │ <──> │ FastAPI + uvicorn │ │
│ └─────────────┘ │ │ │ │ │
│ └────────┬────────┘ └───────────┬─────────────┘ │
│ │ │ │
│ ┌──────────────────────┼──────────────────────────┤ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────────┐ ┌─────────────────────────┐ │
│ │ 日志系统 │ │ 终端执行单元 │ │ Web 仪表盘 │ │
│ │ logger.py │ │ TradingUnit │ │ dashboard.html │ │
│ └─────────────┘ │ × N │ │ │ │
│ └────────┬────────┘ └─────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ QMT 终端 │ │
│ │ xtquant 连接 │ │
│ └─────────────────┘ │
│ │
├─────────────────────────────────────────────────────────────────────────────┤
│ 外部依赖 │
│ ┌─────────────┐ ┌─────────────────┐ ┌─────────────────────────┐ │
│ │ Redis │ │ QMT 终端 │ │ 浏览器客户端 │ │
│ │ Stream │ │ 实盘交易 │ │ HTTP 请求 │ │
│ └─────────────┘ └─────────────────┘ └─────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
```
### 9.2 数据流向图
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ 数据流向 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 聚宽策略 ──> qmt_sender ──> Redis Stream ──> 消息处理循环 │
│ (信号发送端) qmt:{strategy}:real │ │
│ ▼ │
│ 槽位/百分比检查 │
│ │ │
│ ▼ │
│ 订单执行 (QMT API) │
│ │ │
│ ┌───────────────────────┼───────────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ 成交回调处理 错误回调处理 持仓更新 (Redis) │
│ │ │ │ │
│ └───────────────────────┴───────────────────────┘ │
│ │ │
│ ▼ │
│ 日终清算 / 状态同步 │
│ │
├─────────────────────────────────────────────────────────────────────────────┤
│ 监控数据流向 │
│ │
│ 系统状态 ──> API 端点 ──> JSON 响应 ──> Web 仪表盘渲染 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
### 9.3 消息处理流程
1. **消息接收**:系统从 Redis Stream `qmt:{strategy_name}:real` 中读取消息
2. **消息解析**:将 JSON 消息解析为结构化数据,验证必填字段
3. **日期校验**:检查消息日期是否为当天,过期消息丢弃
4. **模式检查**:根据策略配置确定使用槽位模式或百分比模式
5. **槽位/资金检查**:查询策略已占用槽位或账户总资产,判断是否允许新买入
6. **数量计算**:根据资金和价格计算买入股数(向下取整为百股)
7. **订单执行**:调用 QMT API 下单,成功则缓存订单信息
8. **状态更新**:标记虚拟持仓,异步等待成交回调
9. **消息确认**:发送 ACK 确认消息已处理
## 10. 启动与停止
### 10.1 Windows 启动
使用提供的 `start.bat` 脚本启动系统:
```batch
start.bat
```
或手动启动:
```bash
cd qmt
python run.py
```
### 10.2 日志文件位置
系统日志保存在 `qmt/logs/{日期}.log` 目录下,文件名格式为 `2026-01-27.log`。日志按日期自动切分,当日期变化时创建新的日志文件。
### 10.3 端口说明
| 服务 | 默认端口 | 说明 |
|------|----------|------|
| API 服务 | 8001 | Web 仪表盘和 RESTful API 监听端口 |
## 11. 注意事项
1. **QMT 终端要求**:确保 QMT 终端已登录且路径配置正确
2. **Redis 服务**:系统依赖 Redis 运行,请确保 Redis 服务可用
3. **交易日时间**:交易逻辑仅在 09:15-11:30 和 13:00-15:00 期间执行
4. **维护时段**:每日 21:32-21:50 为 QMT 维护时段,此时段不执行重连
5. **权限要求**:确保程序有权限写入 `logs/` 目录
6. **配置文件**Redis 配置优先从 `.env.local` 文件加载,如不存在则使用 `config.json` 中的配置