Python策略结构
每个 TqSdk 程序都遵循同一个结构。理解了 TqApi + wait_update + 数据引用这三件事,你就掌握了整个框架的运行逻辑——后面所有的行情函数、交易函数,都建立在这个骨架上。
TqApi:唯一核心
tqsdk.TqApi 是整个框架的核心类,一个程序只应有一个实例。它负责:
- 建立 WebSocket 连接到行情/交易服务器
- 在内存中维护业务数据截面(行情、K线、账户、持仓)
- 发出交易指令
- 管理协程任务
- 执行策略回测
from tqsdk import TqApi, TqAuth
api = TqApi(auth=TqAuth("快期账户", "账户密码"))
创建 TqApi 时第一个参数是账户,不传则默认使用 TqSim()(本地模拟)。第二个参数 auth 是必填的快期账户认证。
wait_update:程序的心跳
api.wait_update() 是 TqSdk 中最重要的函数。每次调用它时,会发生这些事:
- 发出网络数据包——比如你之前调了
insert_order(),真正的报单指令是在下一次wait_update()时发出的。 - 接收服务器数据包,更新内存中的业务数据截面。
- 让后台任务运行——如
TargetPosTask调仓任务,只在wait_update()时执行。 - 如果没有数据包,则阻塞等待。
因此,策略程序必须反复调用 wait_update():
while True:
api.wait_update() # 等待数据更新
do_something() # 数据有更新时执行你的逻辑
如果不想无限阻塞,可以设置超时:
api.wait_update(deadline=time.time() + 30),超时后返回False。
内存数据:动态引用
TqApi 在内存中维护了一份完整的业务数据截面。通过 get_quote / get_kline_serial / get_account 等函数获取的是动态引用,不是快照:
account = api.get_account()
print(account.balance) # 当前权益
# 后续不需要重新调用 get_account
# 每次 wait_update 后,account.balance 自动更新为最新值
这意味着你只需要调用一次 get_account() 拿到引用对象,之后随时读取它的属性就能获得最新数据。
is_changing:判断什么变了
wait_update() 在任何数据更新时都会返回。要判断你关心的对象是否在本次更新中变化,用 is_changing():
quote = api.get_quote("SHFE.rb2410")
klines = api.get_kline_serial("SHFE.rb2410", 60)
while True:
api.wait_update()
# 判断行情的某个字段是否变化
if api.is_changing(quote, "last_price"):
print("最新价变了:", quote.last_price)
# 判断是否生成了新 K 线
if api.is_changing(klines.iloc[-1], "datetime"):
print("新 K 线:", klines.close.iloc[-1])
| 用法 | 含义 |
|---|---|
is_changing(obj) | 该对象的任意字段有更新 → True |
is_changing(obj, "last_price") | 仅指定字段有更新 → True |
is_changing(obj, ["close", "volume"]) | 列表中任意字段有更新 → True |
一个典型策略结构
以「开仓 → 持有 → 平仓」为例:
from tqsdk import TqApi, TqAuth, TargetPosTask
api = TqApi(auth=TqAuth("快期账户", "账户密码"))
klines = api.get_kline_serial("SHFE.rb2410", 60)
target_pos = TargetPosTask(api, "SHFE.rb2410")
# 第一阶段:等待开仓条件
while True:
api.wait_update()
ma5 = klines.close.iloc[-5:].mean()
if klines.close.iloc[-1] > ma5: # 开仓条件
target_pos.set_target_volume(1) # 目标持仓设为多头 1 手
break
# 第二阶段:等待平仓条件
while True:
api.wait_update()
ma5 = klines.close.iloc[-5:].mean()
if klines.close.iloc[-1] < ma5: # 平仓条件
target_pos.set_target_volume(0) # 目标持仓设为空仓
break
api.close() # 释放资源
这个结构可以总结为:初始化 → 循环(wait_update → 判断 → 动作) → close。
跨交易日重启
建议每个交易日重启策略程序。长时间不重启可能导致合约信息未更新、隔夜委托单残留等问题。如果使用 TargetPosTask,隔夜重启尤为重要。
小结
TqApi是唯一核心,管理连接、数据和任务。wait_update()是心跳,所有收发和后台任务都在这里完成。- 数据对象是动态引用,只需获取一次,自动更新。
is_changing()用来精准判断哪些数据变了。- 程序结束前调用
api.close()释放资源。
理解了这个结构,接下来看具体怎么拿行情数据: 行情接口 TqApi。