前言

个人做国内期货量化时,常把天勤策略先跑在办公笔记本上:Python 进程里 TqApi 连上行情,主循环 wait_update() 推进,螺纹钢 5 分钟均线信号触发后 TargetPosTask 调仓。合盖午休后唤醒,任务管理器里进程还在,屏幕也没报错,但可能半小时没有新成交、本地记的目标仓和 get_position().pos 对不上,甚至重连后重复发单。

原因是休眠挂起网卡,天勤与行情服务器的连接已断,而 Python 进程未必退出;若不检测断连、不 close 重建 TqApi、不按 account-position-order 全量对账,这种故障比进程直接崩溃更隐蔽。下面给笔记本场景下的检测、重连与对账流程,核心看 quote.datetime 是否还在走。

一、休眠后常见异常表现

现象 可能原因
quote.datetime 长时间不变 行情断流
wait_update(deadline) 频繁超时 链路半死不活
委托 status 卡在 ALIVE 断线期间单在交易所,本地未更新
重复开仓 本地 target 与柜台 pos 脱节

二、断连检测怎么做

交易时段内监控:

import time

last_seen = {}

def mark_quote(api, symbol):
    q = api.get_quote(symbol)
    if api.is_changing(q, "datetime"):
        last_seen[symbol] = time.time()

def check_stale(symbols, threshold_sec=300):
    now = time.time()
    stale = [s for s in symbols if now - last_seen.get(s, 0) > threshold_sec]
    return stale

配合 quote.trading_time 或自有交易日历,休市时段不报 stale。也可用 wait_update(deadline=time.time()+60) 返回 False 作为心跳超时信号。

三、重连流程

天勤没有单独的 reconnect 按钮,标准做法是:

  1. 记录断连原因与时间到日志。
  2. api.close() 关闭当前实例。
  3. 重新构造 TqApi(...),重建 TargetPosTask(参数须与之前一致或故意升级版本)。
  4. wait_update() 收齐账户、持仓、委托。
  5. 全量对账:account → position → order,再 set_target_volume 对齐真实世界。

切忌不 close 就再 TqApi() 叠第二个连接,内存与回报会乱。

四、唤醒后的对账顺序

与断线重连专题一致:

  1. get_account() 看权益是否跳变。
  2. 各品种 get_position().pos
  3. get_order() 清理认知外的 ALIVE 单(是否撤单由策略决定)。
  4. 用柜台 pos 重置本地 target,再交给 task。

五、工程习惯

  • 笔记本策略尽量用 TqSim/TqKq 或小额实盘,并设系统「合盖不休眠」若必须无人值守。
  • 生产环境用服务器 + systemd 守护,笔记本只作开发。
  • 外部 watchdog:进程在但 stale 超阈值则 kill 重启整个 Python。

六、外层重启壳子示意

while True:
    api = None
    try:
        api = TqApi(...)
        task = TargetPosTask(api, SYMBOL)
        run_strategy(api, task)
    except Exception as e:
        log("fatal", e)
    finally:
        if api:
            api.close()
    time.sleep(5)  # 仅在外层重启间隔,不在 wait 循环内

内层策略循环里仍禁止 sleep。

七、唤醒后首分钟别急着加仓

重连后对账完成前,设 reconcile_grace=True,忽略 K 线开仓信号,只允许减仓。防止本地 target 旧值导致重复加仓。

八、与 TqNotify 配合

若订阅 TqNotify,断线类通知在唤醒后可能批量涌出,应对 disconnect 类 key 做 5 分钟限频,避免钉钉刷屏。

总结

笔记本休眠导致的不是策略公式失效,而是天勤连接静默断开而进程仍在空转。用 quote.datetimewait_update 超时做交易时段内的心跳,触发 close、重建 TqApi、按 account-position-order 全量对账,再恢复 TargetPosTask,才能把合盖唤醒后的隐患压下去。个人研发若必须本地跑,关闭合盖休眠或改用服务器,比事后补救更省事。

FAQ

1)能否自动 api.close 后无缝续跑?

可以写在外层 while 里,但 task 必须重建,state 要从柜台拉。

2)休眠时挂单会怎样?

交易所仍有效,唤醒后对账以 get_order 为准。

3)TqTimeoutError 和 deadline False 区别?

前者多来自等数据接口异常阻塞,后者是正常超时返回;处理层级不同。

4)Wi-Fi 切换算断连吗?

算,检测逻辑相同。


本文基于天勤 TqSdk 公开 API 整理,不构成投资建议。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐