更新模型与生命周期

本页目录

ExApi(token, account=None) 提供同步 API,内部 I/O 由同步调用推进。

一个实例,一条更新循环#

  • 所有调用必须在创建实例的线程中执行。
  • 不能在运行中的 asyncio 事件循环里直接调用。
  • 长时间 CPU 计算或阻塞业务代码会延迟更新和故障检查。
with ExApi(token) as api:
    quote = api.watch_quote(symbol)
    bars = api.watch_kline(symbol, "1m")
    while api.wait_update():
        # Inspect all watches after the same update.
        if quote.is_changing("last_price"):
            consume_quote(quote.data())
        if bars.is_changing():
            consume_bars(bars.data())

示例中的 consume_quote、consume_bars 是你的业务函数。多个订阅共用一个更新循环;使用独立线程运行同步程序时,应在那个线程里创建、使用并关闭整个实例。跨线程、关闭后调用或在 asyncio 事件循环中直接调用,可能抛出 RuntimeError。

wait_update 的语义#

wait_update(deadline=None) -> bool 等待并发布下一批用户可见更新。

结果含义
True已提交一批可见更新
False到达调用方指定的绝对期限,仍没有更新
异常SDK 运行错误,不用 False 表示致命错误

不指定期限时,调用可能持续等待。

它也负责推进连接恢复、CTP 同步及交易回报。一批更新可能只涉及部分观察对象,返回 True 后仍应分别检查需要的对象。创建观察句柄不代表已有可交易的、最新的数据;K 线初始化读取见 K 线窗口。

有限等待#

下面的片段放在已创建 api 和 quote 的生命周期内:

import time

while True:
    if not api.wait_update(deadline=time.time() + 5):
        print("本次等待到期,继续等待")
        continue
    if quote.is_changing():
        print(quote.data())
  • 时间格式:deadline 是 Unix 秒的绝对时间,不能直接传 5 表示五秒。
  • 超时含义:False 只表示本次等待到期,不代表断线。需要持续运行时,不要写成 while api.wait_update(deadline=...):,否则一次超时就会结束循环。
  • 任务总时限:在循环外计算一次总截止时间,并在循环中检查;不要在每次更新后重新延长期限。

data 返回独立快照#

  • Quote、资金、持仓、订单、成交均通过快照读取;保存的快照不随未来 wait_update() 改变。
  • K 线返回独立 pandas DataFrame,带有 attrs["symbol"] 与 attrs["period"]。在快照上增加指标列不会保留到下一次 data()。
  • 持仓、订单、成交返回只读 Mapping,即使指定了单个合约,也不是单个对象。
  • 断线时仍保留最后一次快照。数据存在不等于有效;交易先检查 trading_status(),行情先检查 timestamp。

is_changing 检查最近一次提交#

is_changing(key=None) 的参数检查内容
不传字段业务字段变化,默认不包含资金的 updated_at
字符串单字段变化
字符串列表其中任意字段变化

变化与“收到了消息”不同,相同字段值的重复回报不会产生字段变化:

  • K 线:只比较末行;新 K 线收盘价与前一根相同,不触发 "close" 变化。判断新周期检查 "timestamp",不能将它当作整个 DataFrame 的变更检测。
  • 资金:金额未变时,funds.is_changing() 可以是 False;检查 funds.is_changing("updated_at") 可观察资金查询完成时间变化。
  • 持仓、订单和成交映射:检查成员字段,成员增减也构成变化;按合约创建的句柄仅检查该合约。
if quote.is_changing(["last_price", "volume"]):
    current = quote.data()
    print(current.last_price, current.volume)

同一合约多次订阅行情返回同一句柄。K 线按 (symbol, period, data_length) 区分句柄;不同长度是不同窗口。仅使用 data()、is_changing() 等公开方法。

清理资源#

优先使用 with ExApi(...) as api:,也可以在 try/finally 中调用 api.close()。

关闭不等于撤单:关闭只释放资源,不会撤销已提交委托。如有未结束订单,退出前需依据业务规则明确处理。

联系我们

微信扫一扫