量化程序 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 推进。

风险提示

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

相关推荐
用户70887690393814 小时前
给传统 SaaS 增加 AI 能力:3个真实落地场景
python
卷无止境14 小时前
FastAPI中间件全解析:请求处理链条上的隐形关卡
后端·python·fastapi
用户03321266636714 小时前
使用 Python 将 HTML 内容添加到 PowerPoint 演示文稿中
python·html
看浪的路人14 小时前
第4讲:MCP Client 开发——连接、发现、调用
windows·python·ai
Swift社区14 小时前
Python 开发环境怎么选?PyCharm、VS Code、Trae 谁更适合 AI 开发?
人工智能·python·pycharm
卷无止境14 小时前
聊聊Web开发里的流式数据 从原理到FastAPI实战
后端·python·fastapi
SMF191914 小时前
【PyCharm】让 PyCharm 使用 .venv 虚拟环境
ide·python·pycharm
修远客14 小时前
感知模块:Agent的眼睛和耳朵 — 三层降级策略让Agent永不"失明"
python·agent
circuitsosk14 小时前
Prompt Engineering进阶:面向复杂业务场景的模板化管理与动态注入策略
python·langchain·prompt·跨境电商·rag·上下文管理·动态注入
Livia要学习15 小时前
Python闭包
开发语言·jvm·python