最近,我做了一件事:做成了一个 AI Agent Skill(名字叫 qmt-strategy-review),让它专门干一件事——评审大 QMT 策略代码+单线程工程分析,出一份可决策的审阅报告。
先说清楚状态:这个 Skill 还没上线,目前只在我本地的 Skill 目录里跑,等上架了我再更新。这篇就用一个真实案例(评审QMT 内置的双均线示例策略)展示它到底产出什么、怎么用、以及它明确不干什么。
真实案例:评审官方双均线示例
我把官方那份双均线实盘示例丢进去,跑出来的汇总表是这样:
第一部分:评审范围说明
本评审只检查代码编写与代码实现层:单线程阻塞、数据层效率、ContextInfo 误用与状态管理、API 签名与枚举值(均已逐一对照 QMT 官方文档核实)、编码声明与乱码风险、Python 代码层错误、回放与重复下单防护、日志与异常处理写法。
两点强调:
- 不检查策略逻辑:双均线金叉/死叉信号是否有效、17/27 参数是否合理、盈亏与风险表现如何,属于策略逻辑范畴,本评审不评价、不预测、不下结论。下文提到“重复下单”指的是代码实现没有防护,不是对策略本身的判断。
- 不收集、不存储策略代码:评审只在当前对话内完成——不落盘、不复制、不写入任何记忆或日志文件,阶段一连改后文件的磁盘副本都不生成。你贴出的代码只用于本次评审。
第二部分:修改意见
汇总表
| 编号 | 级别 | 位置 | 问题一句话 |
|---|---|---|---|
| 严1 | 严重 | L58 | get_history_data 的 dividend_type 传了字符串 ‘front_ratio’,官方定义为 int 0-4 |
| 警1 | 警告 | L72-L80 | waiting_list 只防”未查到委托”,废单后金叉条件持续成立会每个分笔循环报单 |
| 警2 | 警告 | L38-L66 | 每个分笔执行 3 次柜台查询 + 全窗口均线重算,午休也空转,无降频 |
| 提1 | 提示 | L43/L69 | 资金判断用 < 且未留手续费余量,接近临界会产生废单(与警1叠加放大) |
| 提2 | 提示 | L58 | get_history_data 官方已标注【不推荐】,建议迁移 get_market_data_ex |
| 提3 | 提示 | L27/L40 | print 输出账号明文,日志留档建议脱敏 |
| 通2 | 提示 | L17-L18 | account/accountType 是界面注入变量(静态扫描报未定义属预期),但仅限策略交易界面运行 |
总体结论:当前状态不建议直接上实盘。严1 可能直接异常或复权口径错误;最大风险是警1——一笔废单就能触发当日循环报单直到资金耗尽。
逐条详述
严1(严重)dividend_type 参数类型错误
- 现象:
C.get_history_data(..., dividend_type='front_ratio')传了字符串。 - 原因:官方文档定义
get_history_data的dividend_type是 int:0=不复权、1=前复权、2=后复权、3=等比前复权、4=等比后复权。'front_ratio'这种字符串风格是get_market_data_ex的参数体系,用在这里属于传错参数。 - 依据:已经 QMT 官方文档核实(「行情函数」get_history_data 参数表)。
- 改法:想要等比前复权就传
dividend_type=3;或按提2 整体迁移到get_market_data_ex(它的dividend_type确实接受'front_ratio'字符串)。 - 不改会怎样:可能每次调用抛异常(策略停摆),也可能静默按非预期复权口径取数——均线数值失真,信号跟着失真。改后要回归:取数长度、首尾收盘价与主图 K 线一致。
警1(警告)废单后循环报单
- 现象:
waiting_list的语义是”委托在柜台查不到就暂停报单”。但委托一旦被查到(包括废单、已撤),就从列表移除,拦截解除。 - 原因:买入委托若因资金不足/价格笼子等原因成为废单,持仓不会增加,而日线金叉条件在当天会持续满足——于是每个分笔都会重新
passorder,直到可用资金被反复冻结耗尽或收盘。这是典型的缺信号幂等问题。 - 依据:已经 QMT 官方文档核实(「交易函数」委托查询机制与官方完整示例的“未查到委托 + 超时撤单重报 + 目标仓位对比”机制)。
- 改法(局部示意,未落盘):增加当日已报方向标记(如
A.buy_today = True做幂等),或参考官方完整示例,记录全部已报委托的 remark 并结合委托状态做状态机,废单后人工/定时器介入再决定重报。 - 不改会怎样:一笔废单 → 当日几十上百笔重复委托,触犯超单限制还可能被券商风控关注;改后要回归:故意制造一笔废单,确认不会自动重报。
警2(警告)每分笔全量查询与重算,无降频
- 现象:订阅行情后每个 tick 都会进
handlebar,每次都执行 3 次get_trade_detail_data(account/order/position)+ 一次全窗口取数 + 4 次窗口均值计算;11:30-13:00 午休期间也在空转;print未查到委托时每分笔刷屏。 - 原因:只过滤了历史 K 线(
is_last_bar)和交易时段,没有”这根日线走完了没”的判定。 - 依据:已经 QMT 官方文档核实(「系统函数」is_new_bar 释义;官方完整示例采用
run_time定时器模式)。 - 改法:日线信号建议加
C.is_new_bar()做“收根结算”,或整体改为run_time定时器轮询(官方完整示例即此模式);print 加限流。 - 不改会怎样:单只品种尚可容忍,但这是同一客户端所有策略共享的线程开销,多策略叠加时大家一起变慢;改后要回归:信号触发时点是否符合预期(注意 is_new_bar 会把信号挪到收根后,语义有变化,需你确认想要盘中即时还是收根确认)。
提1(提示)资金边界:A.amount < available_cash 用 <(恰好等于时跳过买入),且 int() 截断、未预留手续费——金额贴近可用资金时容易因费用不足产生废单,正好踩中警1的循环报单。可改为类似 A.amount <= available_cash * 0.998 留出费用余量。
提2(提示)API 迁移:get_history_data 官方已标注【不推荐】,推荐 get_market_data_ex,且后者的 dividend_type 接受字符串 'front_ratio'——一次迁移可同时消掉严1。候选写法见第三部分注释。
提3(提示)日志脱敏:L27、L40 直接 print 账号,建议 '****' + A.acct[-4:] 之类的脱敏写法。
通2(提示)界面注入变量:account/accountType 是策略交易界面运行时注入的内置变量(官方示例同样直接使用),静态扫描报“未定义”属预期误报;但在编辑器/回测环境运行会 NameError——这段代码只能在策略交易界面以实盘/模拟方式运行。
已核实无误的部分(正面确认,无需改):
- 状态存模块级
A实例而非ContextInfo,正确规避了深拷贝回滚问题,L13 注释的理解也是对的; C.stockcode + '.' + C.market拼接格式正确(stockcode 返回不带市场的代码,market 返回市场标识);passorder参数:opType 23/24(普通买卖)、33/34(担保品买卖)、orderType 1101(单股单账号按股数)、prType 14(对手价)、price=-1、quickTrade=1 配合is_last_bar()过滤——全部与官方文档一致;get_trade_detail_data三处调用的账号/类型/数据类型参数正确,所用字段m_dAvailable/m_strRemark/m_strInstrumentID/m_strExchangeID/m_nCanUseVolume均与官方数据结构一致;- 无 sleep、无线程库、无全量取数——单线程五条铁律全部未触碰。
第三部分:节选代码 + 注释(原样,逻辑零改动)
1 | #encoding:gbk |
是否需要我落地修改? 如需进入阶段二(届时会先备份 双均线.txt.bak,只改确认过的条目,改完重跑静态审查对比),请回复条目编号,例如「改 通2、严1、警1」或「全改」。
⚠️ 实盘风险提示:涉及真实下单。请先在 QMT「模拟信号模式」或「模拟柜台」中充分验证后,再切换实盘账号;股票受 2% 价格笼子限制,数量超可用会产生废单。
⚠️ 风险提醒与免责声明
- 本回答基于 QMT 官方公开文档与公开社区资料整理,仅供编程学习与技术研究,不构成任何投资建议。
- 实盘前必须在「模拟信号模式」或「模拟柜台」充分验证;未经模拟验证直接实盘,后果自负。
- 具体行为以官方文档、券商柜台与本地客户端实际输出为准,不承诺任何委托结果。
- 因使用本回答中的代码或建议造成的任何盈亏,由使用者自行承担全部责任。
要提醒的是别指望它做的事:它不告诉你能不能赚钱,也不替你决定参数。它给的是”这段代码在工程上站不站得住”,剩下的判断还是你自己的。而且它的输出是 AI 生成的,每条都标了依据,但你最好还是对着官方文档核一眼关键的那几条——尤其是涉及下单的部分。
现状
qmt-strategy-review 目前尚未上线,我是在本地 Skill 目录里装的,配合 QMT 官方 API 文档做查档。等它上架到 Skill 市场我再更新这篇。如果你也在做 QMT 策略,可以留意一下;在那之前,上面这份报告里的七条问题清单本身,也够你拿去对照自己的代码自查一遍了。
策略代码全文和审阅完整版报告请在后台发送“代码评审”获取。
免责声明
- 本文为 AI 工具使用心得与技术分享,仅供编程学习与技术研究,不构成任何投资建议、荐股意见或收益承诺。
- 文中评审意见由 AI 生成,虽已标注官方文档依据,仍可能存在误判;请以 QMT 官方文档与你本地客户端的实际行为为准。
- 涉及的
passorder等交易接口会在实盘模式下真实发出委托,任何策略在实盘前必须先在 QMT「模拟信号模式」或「模拟柜台」中充分验证。- 因使用本文内容、代码或建议造成的任何盈亏,由使用者自行承担全部责任。量化交易涉及真实资金风险,入市需谨慎。
- QMT、迅投 为迅投公司或其关联公司的商标,本文为社区非官方整理,与官方无隶属关系。
- 本文由 AI 创作,请自行判断是否适用。