前言
天勤量化程序的结构可以概括成:创建一个TqApi,订阅合约,在while True里反复调用api.wait_update()。每一次wait_update,天勤会尝试收一批数据包,更新内存里的行情、委托、持仓,并让后台的TargetPosTask有机会发单撤单。若网络卡住、行情服务繁忙、或休市无数据,循环会长时间阻塞——既可能错过风控,也可能让你误以为程序还在正常跑。
天勤提供两种与「等太久」相关的机制:一是wait_update(deadline=时间戳)超时返回False;二是部分接口在等待数据时抛TqTimeoutError异常。两者容易混为一谈。下面按官方api.py、exceptions.py说明区别、为何会出现、以及分级怎么处理。
一、天勤主循环在等什么(架构入门)
| 组件 | 作用 |
|---|---|
TqApi | 连接行情与交易网关,全程序通常一个实例 |
get_quote/get_kline_serial | 订阅后得到对象引用,内容靠 wait_update 刷新 |
wait_update() | 阻塞直到有业务更新或 deadline 到期 |
TargetPosTask | 在 wait_update 内部发单,不调 wait_update 就不交易 |
is_changing(obj, "字段") | 判断本帧该字段是否刚更新 |
没有wait_update,你 print 的quote.last_price可能是几分钟前的旧值。
二、deadline 是什么
deadline是可选参数,类型为浮点数,表示 Unix 时间戳(从 1970-01-01 起的秒数,可用time.time()加秒数得到)。
官方文档要点:
- 默认无 deadline:一直等到有数据更新。
- 若当前时间超过 deadline 且仍无业务数据更新,返回
False。 - 若有数据更新或内部任务执行,返回
True。 - deadline 过小且循环里计算很重,可能导致任务堆积,文档称为非简单用法。
importtime deadline=time.time()+30ifnotapi.wait_update(deadline=deadline):log("wait_update 30s 无更新")on_wait_timeout()返回False不等于连接已断,可能是休市无包、或网络暂时无推送;要结合quote.datetime是否推进、是否交易时段判断。
三、TqTimeoutError 是什么
TqTimeoutError定义在tqsdk.exceptions,在获取行情、K 线、tick、设置风控规则等同步等待超时时抛出,错误信息常含「请检查客户端及网络是否正常」。
与 deadline 返回False的区别:抛异常说明该次等待特定资源的同步路径失败,多见于启动时首包get_kline_serial迟迟不来、或内部链路超时。
fromtqsdkimportTqApi,TqAuth,TqTimeoutErrortry:api.wait_update()exceptTqTimeoutErrorase:log("TqTimeoutError",str(e))recover_from_timeout()四、分级处理建议
| 级别 | 现象 | 建议 |
|---|---|---|
| 轻 | 单次 deadline 返回 False | 计数,连续 N 次再告警 |
| 中 | 交易时段连续 False | 暂停set_target_volume,只监控 |
| 重 | TqTimeoutError 或长时间无 datetime | api.close(),守护进程拉起,全量对账 position/order |
休市时quote.datetime不更新,用交易日历过滤,避免凌晨误报。主循环两次wait_update之间勿长时间sleep或同步 IO,否则会造成「伪超时」。
五、与 TargetPosTask
task 发单发生在wait_update内;你若因怕超时长期不调wait_update,调仓会停住,但行情断更同样危险。常见做法:主循环带 60~120 秒 deadline,超时后走on_wait_timeout,仍决定是否退出或重连。
协程里不能调用wait_update,文档写明需用register_update_notify,否则架构不对。
总结
wait_update 超时要先分清:是 deadline 正常返回 False,还是 TqTimeoutError 打断,以及当时是否在交易时段、datetime 是否还在走。天勤把整个实盘的「心跳」绑在 wait_update 上,理解这一点后,才能判断为何网络问题会表现为「不调仓」或「数据不更新」。把轻中重响应和休市过滤写进主循环,再配合重连后读get_position全量对账,程序就不会在死等和频繁重启之间来回摆。
FAQ
1)deadline 设多少?
交易时段 30~120 秒常见,结合品种与网络试。
2)一次 False 就要 close 吗?
不必,连续多次再处理。
3)回测会超时吗?
TqBacktest本地推历史,少见,逻辑可保留。
4)怎么区分休市与断线?
休市 datetime 本就不跳;交易时段长时间不跳更可疑。
风险提示
以上内容用于超时处理参考,不构成投资建议。