取消观察列表行情
流式一档行情会持续占用订阅资源。只要不再需要某个合约的行情,就应该调用 cancelMktData() 取消。
app.cancelMktData(tickerId)tickerId 必须和请求时传给 reqMktData() 的编号一致。
# 请求 AAPL 一档行情。app.reqMktData(97701, aapl_stock(), "", False, False, [])
# 不再需要时取消。app.cancelMktData(97701)什么时候需要取消
Section titled “什么时候需要取消”| 场景 | 是否取消 |
|---|---|
| 用户从观察列表移除合约 | 需要取消。 |
| 页面关闭或切换账户 | 需要取消。 |
| 策略停止运行 | 需要取消。 |
| 快照请求 | 通常不需要手动取消。 |
| 请求因为权限错误没有建立 | 取消可能返回 300。 |
参考边界样例
Section titled “参考边界样例”请求 AAPL 流式一档行情后,因为行情权限不足,订阅没有真正建立。随后取消该 tickerId 时,TWS 返回:
ERROR=reqId=97701;name=streaming;code=300;msg=无法使用tickerId找到EId::97701这通常表示要取消的行情请求并不存在或已经被拒绝。它要结合前面的错误一起看:
ERROR=reqId=97701;name=streaming;code=10089;msg=请求的市场数据对于API来说需要额外订阅...:AAPL NASDAQ.NMS/TOP/ALL也就是说,根因是行情权限不足,300 是取消未建立订阅时的连带结果。
程序应维护订阅状态:
active_market_data = set()
def request_market_data(req_id, contract): app.reqMktData(req_id, contract, "", False, False, []) active_market_data.add(req_id)
def cancel_market_data(req_id): if req_id in active_market_data: app.cancelMktData(req_id) active_market_data.discard(req_id)如果 error() 收到明确的权限错误或合约错误,也可以把对应 reqId 从活跃订阅集合中移除。