
TqSdk 新手遇到“行情不动、信号重复、订单没成交、持仓不对、程序关不掉”时最容易同时修改很多代码。更有效的排查顺序是先确认环境与事件循环再检查数据变化和规则触发最后核对订单、成交与持仓。一次只定位一层现象才不会被新的修改覆盖。行情一直不动先看 wait_updateget_quote或get_kline_serial返回的是动态引用数据需要wait_update推进。没有事件循环时反复读取只会得到同一份内存快照加sleep也不会主动接收更新。while True: api.wait_update() if api.is_changing(quote, last_price): print(quote.datetime, quote.last_price)若仍无输出按环境、认证、合约代码、交易时段和字段有效性依次检查。非交易时段没有新价格可能是正常情况不要立刻把它解释为断线。还要区分“API 收到更新”和“关注字段变化”。本轮可能只有其他合约或盘口字段变化last_price分支不执行并不代表事件循环失效。临时记录更新计数与最后行情时间比无限打印整个 Quote 更清楚。信号反复出现先看触发事件和状态当前 K 线的收盘价在周期内会多次变化。如果策略只应每根新 K 线判断一次却监听close同一条件就会重复触发。应监听末行datetime变化并使用已完成数据。即使信号每根线只算一次同一方向也可能连续出现。程序需要保存当前目标或上次已处理信号目标没有变化时不重复提交。防重复不能只靠等待几秒因为条件仍可能持续为真。重启后内存状态丢失也是重复来源。启动时先读取持仓和活动委托恢复最后业务状态再允许新的信号进入执行层。下单后没有成交不要直接再下一笔insert_order立即返回委托引用但请求在后续wait_update才发送。先检查订单status、volume_left与last_msg再查看成交记录和盘口。订单可能存活、部分成交、撤销或被拒绝。限价没有达到对手盘、市场没有可用对手价、交易时段或合约状态不合适都可能让订单未成交。不能因为行情中出现过某个价格就认定自己的委托应当成交。需要撤单时调用cancel_order后继续等待回报。若期间出现部分成交重新下单只处理剩余目标。直接复制原订单会导致持仓超出预期。持仓不符合预期沿订单链回查先看多头、空头与净持仓再看该合约所有活动委托。净仓为零可能是完全空仓也可能多空对锁当前仓位正确也可能仍有等待成交的订单。然后按业务意图找到订单再按订单找到成交记录核对方向、开平、手数和价格。成交总量能否解释持仓变化是比“代码里写了多少手”更可靠的检查。若使用 TargetPosTask同一合约不要同时手工insert_order也不要创建多个任务实例。两套控制逻辑会根据同一持仓各自行动产生互相冲突的订单。账户里存在人工交易或其他策略时还要确认持仓归属。一个策略不能把整个账户持仓都当成自己产生也不能擅自调整未知仓位。数据计算结果奇怪先看动态序列K 线和 Tick 序列会随事件循环更新。需要固定计算时先复制快照已完成 K 线通常排除正在形成的末行。窗口不足和空值不应直接填零。跨合约、跨周期计算要按时间对齐不能因为两个 DataFrame 行数相同就按行号相减。动态窗口滚动后iloc[-2]只是当前倒数第二行不是永久标识。回测结果异常好时检查未来数据是否使用当前未完成 K 线最终值是否反向填充是否对全样本一次性标准化。公式能运行并不代表只使用了当时可见的信息。程序停不下来核对退出职责所有主循环都应处在可捕获退出的结构中并在finally调用api.close()。异步任务由同一个 API 管理不能留下没有监控的无限协程。交易程序退出前先停止新信号检查活动委托并按规则撤销或交接。撤单同样需要事件循环等待结果。强制结束进程可能让账户状态继续变化下一次启动也更难恢复。若程序因异常退出保留完整堆栈和最后状态不要捕获所有异常后静默继续。一个后台任务已经死亡而主进程仍在运行比明确失败更危险。最小复现怎样写才有效排查时从原程序复制最少内容一个账户环境、一个合约、一类数据、一个触发条件和必要日志。先去掉指标、文件保存、消息通知和多合约逻辑证明基础链路是否正常。最小复现要保留真正的失败条件。若问题是新 K 线重复触发就保留is_changing与计数若问题是订单状态就使用模拟账户保留订单循环。删到只剩一个print却不再出现原问题也无法帮助定位。记录 Python 与 TqSdk 版本、运行时间、合约、账户类型和完整异常但不记录密码。给别人协助时提供可运行的最小脚本和实际输出不只描述“不能交易”。修复后把同一最小复现变成回归测试再把改动放回原程序。一次加入一个模块确认问题没有重新出现。这样能找到真正修复点而不是靠多处改动碰巧让现象消失。若最小脚本无法复现就回到原程序比较环境、账户类型、合约、运行时间和并发任务找出被删除的必要条件。不要为了让示例“看起来简洁”而隐藏真正触发故障的那一层。排查记录最后要写明根因和验证方式而不只写“已修复”。同类现象下一次出现时可以先检查已知原因若检查不符再建立新的最小复现避免反复靠猜测改代码。新手排错清单环境与认证可用合约和交易时段正确wait_update持续推进。用is_changing检查正确字段新 K 线与当前线变化分开。信号、目标和活动委托有防重复状态重启先恢复账户事实。订单按状态、剩余手数、成交和持仓顺序核对不用行情代替成交。动态数据先确认长度、空值与时间异常退出保留堆栈并安全关闭。排错真正需要的是一条能复现的因果链而不是更多猜测。先证明数据是否更新再证明信号是否正确再证明订单和持仓如何变化绝大多数常见问题都会落到一个可以修复的具体位置。