前言

天勤量化程序的结构可以概括成:创建一个 TqApi,订阅合约,在 while True 里反复调用 api.wait_update()。每一次 wait_update,天勤会尝试收一批数据包,更新内存里的行情、委托、持仓,并让后台的 TargetPosTask 有机会发单撤单。若网络卡住、行情服务繁忙、或休市无数据,循环会长时间阻塞——既可能错过风控,也可能让你误以为程序还在正常跑。

天勤提供两种与「等太久」相关的机制:一是 wait_update(deadline=时间戳) 超时返回 False;二是部分接口在等待数据时抛 TqTimeoutError 异常。两者容易混为一谈。下面按官方 api.pyexceptions.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 过小且循环里计算很重,可能导致任务堆积,文档称为非简单用法。
import time

deadline = time.time() + 30
if not api.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 迟迟不来、或内部链路超时。

from tqsdk import TqApi, TqAuth, TqTimeoutError

try:
    api.wait_update()
except TqTimeoutError as e:
    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 本就不跳;交易时段长时间不跳更可疑。

风险提示

以上内容用于超时处理参考,不构成投资建议。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐