跳转到内容

行情需要额外订阅

当 TWS API 返回“请求的市场数据对于 API 来说需要额外订阅”时,通常说明合约可以识别,但账户没有这类 API 行情权限。

模拟账户请求 AAPL 顶层行情时返回:

ERROR=reqId=99102;code=10089;msg=请求的市场数据对于API来说需要额外订阅。点击“市场数据连接”对话框中的链接获取更多详情。:AAPL NASDAQ.NMS/TOP/ALL

这个错误和合约定义错误不同。合约定义错误通常是 200,说明 TWS 找不到证券定义;10089 更偏向权限或行情订阅问题。

from ibapi.contract import Contract
def aapl_contract():
contract = Contract()
contract.symbol = "AAPL"
contract.secType = "STK"
contract.exchange = "SMART"
contract.currency = "USD"
contract.primaryExchange = "NASDAQ"
return contract
app.reqMarketDataType(1) # 请求实时行情类型
app.reqMktData(99102, aapl_contract(), "", False, False, [])

如果账户没有对应 API 行情权限,就可能收到 10089。这时不是 Python 代码写错,也不是 TWS 没连上。

同一类行情权限问题也可能出现相关代码:

代码常见含义处理方式
10089API 行情需要额外订阅,消息里可能提示延迟行情可用检查行情订阅,或显式请求延迟行情。
10167实时行情不可用,当前显示延迟市场数据标记数据为延迟,不要当作实时行情。
10168行情未订阅,延迟市场数据未启用尝试 reqMarketDataType(3),或检查是否有可用延迟行情权限。
步骤目的
先用 reqContractDetails() 验证合约确认不是合约字段错误。
查看错误码是否为 10089判断是否为行情订阅问题。
查看 TWS 中该标的是否显示实时或延迟行情对照账户实际权限。
尝试延迟行情类型用于判断是否能获取延迟数据。
检查 IBKR 行情订阅API 行情可能需要对应市场数据权限。

样本中,行情订阅因权限错误没有成功建立,随后调用 cancelMktData(99102) 又返回:

ERROR=reqId=99102;code=300;msg=无法使用tickerId找到EId::99102

这表示 TWS 找不到这个有效行情订阅。它不是新的合约问题,而是前一个订阅失败后的连带结果。

active_market_data_req_ids = set()
def start_market_data(app, req_id, contract):
app.reqMktData(req_id, contract, "", False, False, [])
active_market_data_req_ids.add(req_id)
def stop_market_data(app, req_id):
if req_id in active_market_data_req_ids:
app.cancelMktData(req_id)
active_market_data_req_ids.remove(req_id)

正式系统里还应根据 error() 回调把失败订阅从活跃集合中移除,避免重复取消无效 reqId