量化程序 while True 一直跑 CPU 很高:天勤降频与字段过滤

前言

国内期货量化程序跑起来后,结构往往是 while True 里反复调用行情接口等待更新------在天勤 TqSdk 里就是 api.wait_update()。这是正常的:程序要一直活着等交易所和期货公司的业务数据 ,并不是 while 本身有问题。读者若从股票日线回测转过来,容易以为"循环越少越好";在期货 tick 和分钟线场景里,循环可以很勤,但每次循环里干什么决定了 CPU 会不会被打满。

常见现象是:策略逻辑没错,任务管理器里 Python 却长期占满一个核,风扇狂转,日志刷屏,可交易次数并没增加。原因之一是:每一帧行情更新(盘口跳一下、K 线 high/low 变一下、持仓浮盈变一下)都触发整段均线、多合约循环甚至写盘,属于算得太勤 ,而不是天勤"推送太密"。另一类原因是循环里 sleep、同步请求、大段 pandas------那会导致行情滞后 ,和 CPU 高是不同病,本文重点讲前者,并说明如何用天勤的 is_changing字段级过滤

下文默认你已有一个能连上模拟盘的 TqApi,并订了至少一个期货合约的 quote 或 K 线;不默认你熟悉 is_changing 的参数写法。

一、先分清:CPU 高和"收不到行情"不是一回事

现象 常见原因 读者可观察到的表现
CPU 占用高 每帧全量计算、对象级 is_changing quote 时间在走,机器发烫
行情滞后 sleep、网络 IO、循环体过长 quote.datetime 明显落后

天勤每次 wait_update() 收到业务包后,会更新内存里的行情、K 线、委托等对象。若你在每一次更新后都跑完整策略,而期货盘口一秒内可能多次变动,CPU 就会被无意义的重复计算吃掉。

二、对象级 is_changing 为什么容易"空转"

is_changing(obj) 不指定字段时,表示该对象任意字段本帧有更新即为 True。对 K 线 DataFrame 的一行来说,open/high/low/close/volume 任一变化都会成立;对 quote 来说,买卖盘、最新价变动都会成立。

错误示范(逻辑上能跑,但极耗 CPU):

python 复制代码
while True:
    api.wait_update()
    if api.is_changing(kl):  # kl 整表任一列变都可能 True
        heavy_compute()      # 内含多均线、多合约、打印

在螺纹钢活跃时段,这相当于把"每秒上百次 tick 更新"都当成"要重算策略",CPU 飙高是必然结果。

三、字段级过滤:只在你关心的业务变化时算策略

天勤允许 is_changing(obj, "字段名") 或传入字段列表。对按 K 线收盘做决策的期货策略 ,应盯住最后一根 K 线上的 datetime 字段------该字段来自行情服务写入 K 线表,表示这根 bar 的时间标签;当新的一根 K 线生成 时,最后一行的 datetime 会变化,通常意味着上一根已收盘,此时才适合用 iloc[-2] 算信号(详见专题文)。

python 复制代码
kl = api.get_kline_serial("SHFE.rb2510", 300, data_length=200)  # 300 秒=5 分钟线

while True:
    api.wait_update()
    if not api.is_changing(kl.iloc[-1], "datetime"):
        continue
    heavy_compute_on_bar_close()

依赖最新价 的短线规则,可改为 is_changing(quote, "last_price"),并自行加节流(例如同一秒内只处理一次),避免与 K 线策略混用两套触发条件。

持仓核对不必每 tick 打印,可仅在 is_changing(pos, "pos_long")pos_short 变化时记录,这与期货实盘里"成交回报到了才改仓位"的节奏一致。

四、计算与 IO 仍要外移

即使过滤正确,若 heavy_compute 里仍做全样本滚动回归、写大 CSV、同步调 webhook,单次循环耗时过长仍会拖慢 wait_update 调用频率,间接造成回报延迟。建议:指标在 bar 收盘算一次;日志批量写;通知进队列由别的线程发送,主循环只入队。

五、和 TargetPosTask 的叠加效应

国内期货程序化里,天勤 TargetPosTask 负责把净持仓调到目标手数,内部可能在 wait_update 时撤单、按最新对价重挂。行情剧烈时 task 工作频率也会上升。若同一帧你还做大规模 pandas 运算,CPU 会叠加。策略层应把"算信号"严格放在 bar 或仓位变化触发上,而不是每个 tick。

总结

期货量化里 while True + wait_update 是常态;CPU 过高多半是因为在过多的行情帧上跑了完整策略 。天勤提供 is_changing 的字段参数:K 线策略请用最后一根行的 datetime (由 get_kline_serial 返回的表提供)判断新 bar;盘口策略再选 quote 的具体字段;持仓变动用 position 的具体字段。

把"每一帧"变成"业务上需要反应的那一帧",CPU 会降到与策略频率匹配的水平(例如 5 分钟策略大约几分钟才算一次)。若你同时遇到行情变慢,再排查 sleep 和阻塞 IO,两类问题分开处理。

FAQ

1)wait_update 本身占 CPU 吗?

等待网络时线程阻塞,一般不应占满 CPU;占满核多半是循环体内的 Python 计算。

2)多个期货合约怎么过滤?

每个合约一条 kl,分别 is_changing(kl[s].iloc[-1], "datetime"),未变的合约 continue。

3)回测也很慢,能用同样办法吗?

可以,历史回放同样会产生大量帧,过滤后回测速度往往明显提升。

4)不用 is_changing,改用 sleep(1) 行吗?

会阻塞行情与发单,国内期货程序化不推荐用 sleep 代替 bar 推进。

风险提示

本文讨论程序性能与结构,不构成投资建议。

相关推荐
aqi0021 小时前
15天学会AI应用开发(九)利用Chroma持久化向量数据
人工智能·python·大模型·ai编程·ai应用
金銀銅鐵21 小时前
借助 Pygame 探索最大公约数的规律
python·数学·游戏
ServBay2 天前
9 个 Python 第三方库推荐,不用 AI 都好像多出一个团队
后端·python
用户8356290780512 天前
如何使用 Python 添加和管理 Excel 批注(完整示例)
后端·python
用户8356290780512 天前
使用 Python 管理 Excel 工作表:创建、复制、删除与重命名
后端·python
荣码2 天前
LangGraph多Agent协作:3个Agent干活比1个强,但我踩了4个坑
java·python
用户8356290780513 天前
Python 操作 PDF 附件:添加、查看与管理指南
后端·python
宇宙之一粟3 天前
乐企版式文件生成平台
java·后端·python
学测绘的小杨4 天前
CompassFusion:一个从 GNSS 到 GNSS/INS 组合导航的独立工程包
python
zzzzzz3104 天前
当产品经理说这个很简单:我用Python自动化处理奇葩需求的实战指南
python·pycharm·产品经理