取消逐笔数据
逐笔数据是实时订阅。只要不再需要,就应该调用 cancelTickByTickData() 取消。
官方参考:Tick-by-Tick Data
app.cancelTickByTickData(reqId)reqId 必须和 reqTickByTickData() 请求时使用的编号一致。
app.reqTickByTickData(97901, aapl_stock(), "Last", 0, False)
# 不再需要成交逐笔数据时取消。app.cancelTickByTickData(97901)什么时候取消
Section titled “什么时候取消”| 场景 | 说明 |
|---|---|
| 用户关闭行情页面 | 取消对应逐笔订阅。 |
| 策略停止运行 | 取消所有策略使用的逐笔订阅。 |
| 切换标的 | 取消旧标的,再请求新标的。 |
| 收到权限错误 | 订阅通常没有建立,可从程序状态中移除。 |
| 准备换用历史逐笔 | 先取消实时逐笔,避免同一合约重复订阅和限频问题。 |
参考边界样例
Section titled “参考边界样例”AAPL 逐笔行情权限不足时,请求没有真正建立。随后取消时 TWS 可能返回:
ERROR=reqId=97901;type=Last;code=300;msg=无法使用tickerId找到EId::97901ERROR=reqId=97902;type=BidAsk;code=300;msg=无法使用tickerId找到EId::97902ERROR=reqId=97903;type=MidPoint;code=300;msg=无法使用tickerId找到EId::97903ERROR=reqId=97904;type=AllLast;code=300;msg=无法使用tickerId找到EId::97904这里的 300 要和前面的 10189、10089 一起理解:根因通常是行情权限不足、产品不支持该逐笔类型,或订阅没有建立;取消未建立的订阅时,就可能找不到对应 ticker。
维护本地订阅状态时,收到权限错误后应把该 reqId 标记为失败:
active_tick_by_tick = set()
def request_last_ticks(req_id, contract): app.reqTickByTickData(req_id, contract, "Last", 0, False) active_tick_by_tick.add(req_id)
def cancel_last_ticks(req_id): if req_id in active_tick_by_tick: app.cancelTickByTickData(req_id) active_tick_by_tick.discard(req_id)如果 error() 收到 10189、10089、200 等明确失败原因,也应从活跃订阅集合中移除。