大QMT文件 IPC Fallback¶
大QMT文件 IPC 是 easy_qmt_trader 直连失效时的交易降级通道:miniQMT 策略端把订单写入 C:\QuantIPC\{account_id}\orders\pending,大QMT 内置 Python 脚本 QMT_trade_executor.py 读取后用大QMT授权执行下单,并把账户快照和成交回执写回共享目录。
适用场景¶
| 场景 | 是否适用 |
|---|---|
券商收紧 miniQMT xttrader 权限 |
适用 |
| 大QMT客户端已登录并具备交易授权 | 适用 |
| 多账号同机隔离运行 | 适用 |
| 高频、打板、tick级抢单 | 不适用 |
已验证能力¶
实机调试确认:
- 模型交易模式会把
get_trade_detail_data、passorder、cancel注入到globals()。 ContextInfo主要提供行情和上下文能力,没有发现order_stock、query_stock_asset、cancel_order等交易方法。xttrader + StockAccount可用于只读快照,并作为下单首选参数形式。- 休盘时资产字段可能为 0,但持仓仍可返回,需要快照层做数据清洗。
- 光大金阳光 QMT 的“模型交易”入口在非交易日可能只触发一次策略回调;当前 executor 在
init()中进入前台循环,持续轮询 IPC。 - 大QMT 策略容器可能在回调返回后回收后台线程,因此不能把后台 worker 当作主要保活方案。
- PowerShell 写出的 UTF-8 BOM 订单文件可正常解析;坏 JSON 会立即写
done/error,不再等待孤儿恢复。 - 空仓卖出等柜台拒单场景已验证:
order_stock直接返回无效委托号时写done/rejected;委托查询返回order_status=57时也映射为rejected。
目录约定¶
C:\QuantIPC\
TEST_ACC_2\
config.json
status\
heartbeat.json
account.json
orders\
pending\
processing\
done\
done_archive\
cancel\
config.json 由策略端创建,至少包含:
快照口径¶
account.json 由大QMT端写入。当前口径:
source标识来源,优先xttrader,失败时 fallback 到vba。- 过滤
volume<=0的伪持仓。 market_price=0且market_value>0时按market_value / volume反推参考价。total_asset<=0但有市值时,兜底为available + market_value。
示例:
{
"timestamp": "2026-07-12 11:56:40",
"account_id": "TEST_ACC_2",
"source": "xttrader",
"total_asset": 13356.0,
"available": 0.0,
"market_value": 13356.0,
"positions": [
{
"stock": "600509.SH",
"volume": 1800,
"available": 1800,
"cost": 6.914,
"market_price": 7.42,
"market_value": 13356.0
}
]
}
订单回执口径¶
大QMT端处理订单时采用“先文件状态、后交易 API”的顺序,尽量把不确定性收敛在 done/ 回执里:
cancel/cancel_<order_id>.json如果在下单前已存在,executor 直接写done/cancelled,不会连接交易 API。orders/pending/中的 JSON 使用utf-8-sig读取,兼容 PowerShellSet-Content -Encoding UTF8产生的 BOM。- 订单 JSON 无法解析时立即写
done/error,并清理processing/,不再等默认 120 秒的残留恢复。 order_stock返回空值、负数或 0 时写done/rejected。query_all_orders()返回 QMT 废单状态57时写done/rejected,避免误判为超时撤单。
运行与日志¶
推荐在大QMT中使用模型交易入口部署 QMT_trade_executor.py。若界面里没有“定时运行”选项,直接使用“模型交易/实盘/运行”,不要勾选“启动本地 python”。正常日志应类似:
[11:56:39.900] foreground loop started by init pid=12345 interval=1.000s root=C:\QuantIPC
[11:56:40.467] [TEST_ACC_2] snapshot xttrader: total=13356 positions=1 via asset=StockAccount pos=StockAccount
[11:56:40.482] tick ok accounts=2 ticks=1 worker=False
如果看到连续高频 tick start/tick done,说明运行的仍是旧脚本,应重新粘贴最新版本。
如果每次手动运行只看到一次 tick ok accounts=... ticks=1,之后 heartbeat.json 不再刷新,通常不是交易 API 卡死,而是旧版仍在依赖后台线程。请确认已更新到带 foreground loop started by init 的新版脚本,并重新编译、保存、运行。
如果日志里继续新增 worker start requested by top-level 或旧格式临时文件 heartbeat.json.<pid>.tmp,通常说明大QMT里仍有旧实例残留。应先停止策略,必要时重启大QMT客户端,再运行最新版脚本。
验证通过的文件状态:
C:\QuantIPC\{account_id}\status\heartbeat.json修改时间持续贴近当前时间。C:\QuantIPC\{account_id}\status\account.json周期更新;休盘时资产字段可能为 0,但持仓市值应能正常返回或兜底。tick ok accounts=... ticks=...中的ticks持续递增。- 在模型交易前台循环形态下,
worker=False是正常状态;它表示没有额外后台 worker 参与保活。
风险控制¶
- 下单前策略端检查
heartbeat.json,大QMT离线时快速失败。 - 大QMT端处理
processing/超龄文件时写error回执并清理,不重发订单。 done/目录按保留时间归档到done_archive/,避免长期运行膨胀。- 外部交易 API 调用都有超时保护,避免 QMT API 偶发卡死拖住主循环。
- 大QMT端写
done/、status/account.json、status/heartbeat.json时使用唯一临时文件名和短重试,降低 Windows 文件锁导致的WinError 32风险。 - 大QMT端日志按日期写入,同时受
QMT_IPC_LOG_MAX_BYTES和QMT_IPC_LOG_BACKUP_COUNT限制,避免长期运行写满存储介质。
调试顺序¶
- 确认
heartbeat.json持续更新。 - 确认两个账号都生成
account.json,且source=xttrader。 - 确认持仓字段可信:无零股伪持仓,休盘参考价可反推。
- 先验证预取消链路:先写
cancel/cancel_<order_id>.json,再写pending/ord_<order_id>.json,确认done/cancelled且日志没有order seq=。 - 验证拒单链路:用空仓账号小数量卖出不可成交标的或明显会被柜台拒绝的场景,确认
done/rejected、filled_volume=0。 - 有效委托号 + 撤单链路建议等交易时段再测:用极低成交概率限价单拿到正
seq后立即写 cancel 文件,确认inflight cancel和最终回执。 - 最后才做最小数量、有效价格的真实下单验证。