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 中最重要的函数。每次调用它时,会发生这些事:

  1. 发出网络数据包——比如你之前调了 insert_order(),真正的报单指令是在下一次 wait_update() 时发出的。
  2. 接收服务器数据包,更新内存中的业务数据截面。
  3. 让后台任务运行——如 TargetPosTask 调仓任务,只在 wait_update() 时执行。
  4. 如果没有数据包,则阻塞等待

因此,策略程序必须反复调用 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