
前言策略凌晨还好好的早上开盘发现quote.datetime不动、日志也不刷新了——这种“假死”在长跑程序里很常见。原因可能是网络、主循环阻塞、API 未继续wait_update也可能是进程还在但数据截面没更新。要先区分进程活着但没数据和进程已经挂掉。天勤程序以wait_update为心跳官方还提供超时返回、断线后的数据恢复等机制团队里常与TqNotify、持仓核对专题一起用。下面按概率从高到低列原因和对应处理。一、主循环阻塞最常见现象进程 CPU 高或卡在某一函数wait_update很久才调用一次。典型诱因time.sleep等待下一根 K 线同步 HTTP、写库、大段 pandas 计算死循环里continue前未调用wait_update处理用is_changing(kl.iloc[-1], datetime)代替 sleep重活放队列或收盘后批处理。在循环里打耗时超过 200ms 就要优化。二、网络与连接现象进程在跑wait_update仍调用但quote.datetime长期不前进。可能原因宽带/VPN 抖动、机房到行情网关中断笔记本休眠唤醒后 TCP 半开处理用wait_update(deadlinetime.time()N)做周期心跳超时返回 False 时打告警并尝试api.close()后重启进程重启策略要配合状态持久化专题外层用进程管理器systemd、nssm保证崩溃自动拉起具体断线重连行为以当前 TqSdk 版本为准恢复后应用get_position与策略记忆对账。三、订阅与合约问题现象只有某一个 symbol 没行情其他正常。检查合约代码是否写错交易所前缀、大小写是否用了已退市月份夜盘合约白盘未订阅用get_quote后至少一次wait_update文档提示刚订阅时datetime可能为空需区分“从未收到”和“中途停收”。四、协程里误用 wait_update若在 asyncio 协程里调用wait_updateAPI 会抛不能在协程中调用 wait_update。有的同事把异常吞掉表现为策略静默。协程环境应使用register_update_notify与同步策略写法分开不要混在同一个文件两种模型。五、TargetPosTask 与主循环抢时间TargetPosTask在每次wait_update时可能撤单重报。若合约波动剧烈task 频繁改价主循环若还在同一帧做重计算会拉长两次wait_update间隔间接表现为行情处理变慢。处理字段级is_changing缩小计算面task 参数pricePASSIVE撤单更多慎用。六、资源泄漏与未 close反复启动脚本而不api.close()长时间可能耗尽连接或文件句柄。规范进程退出路径正常/异常都close()。七、恢复后的核对步骤重启进程确认订阅列表与配置wait_update后打印各quote.datetimeget_position与策略持久化状态对比有在途单则get_order看清是否需人工撤单八、运维层建议手段作用进程外心跳脚本 5 分钟无日志则告警TqNotify / 钉钉柜台断线、成交类事件集中转发结构化日志每帧记录quote.datetime便于画图定位断点总结长时间不收行情先查主循环是否阻塞wait_update再查网络与合约订阅然后查协程误用、task 频繁撤单、未 close 泄漏。恢复后按 position、order 与持久化状态对账。预防靠字段级过滤、避免 sleep、deadline 心跳、进程守护与日志时间戳监控。天勤模型下没有独立“行情线程”主循环健康度几乎等于行情健康度。FAQ1wait_update 一直阻塞算卡住吗无 deadline 时可能长时间阻塞等待数据属正常若交易所休市datetime 不变也正常要配合交易日判断。2TqTimeoutError 是什么部分等待操作超时会抛此异常与wait_update(deadline...)返回 False 不同查阅版本文档分级处理。3多合约只有一个不动优先查该 symbol 代码与是否仍在交易。4回测会“卡住”吗回测数据播完会BacktestFinished属于结束而非断线。风险提示本文用于运维与开发排查不构成投资建议。