请求二档行情
reqMktDepth() 用来订阅某个合约的市场深度。它是持续订阅接口,请求成功后会不断通过 updateMktDepth() 或 updateMktDepthL2() 推送盘口变化。
官方参考:Market Depth - Requesting
app.reqMktDepth( reqId, contract, numRows, isSmartDepth, mktDepthOptions,)Python 示例:请求 AAPL SMART 深度
Section titled “Python 示例:请求 AAPL SMART 深度”import threadingimport time
from ibapi.client import EClientfrom ibapi.contract import Contractfrom ibapi.wrapper import EWrapper
class DepthApp(EWrapper, EClient): def __init__(self): EClient.__init__(self, self) self.ready = threading.Event() self.errors = []
def nextValidId(self, orderId: int): # 收到 nextValidId 说明 API 连接已经完成握手,可以开始发送请求。 self.ready.set()
def updateMktDepth(self, reqId, position, operation, side, price, size): # 普通二档盘口更新。真实项目里不要只 print,要维护盘口快照。 print("DEPTH", reqId, position, operation, side, price, size)
def updateMktDepthL2(self, reqId, position, marketMaker, operation, side, price, size, isSmartDepth): # L2 盘口更新,多了 marketMaker 或交易所标识。 print("DEPTH_L2", reqId, position, marketMaker, operation, side, price, size, isSmartDepth)
def error(self, reqId, *args): # 不同 TWS API 版本的 error 回调参数可能略有差异。 # 这里统一取出错误码和错误消息,便于排查 2152 等权限问题。 if len(args) >= 3 and isinstance(args[0], int) and args[0] > 1_000_000_000_000: error_code = int(args[1]) error_message = str(args[2]) elif len(args) >= 2: error_code = int(args[0]) error_message = str(args[1]) else: error_code = -1 error_message = str(args)
self.errors.append((reqId, error_code, error_message)) print("ERROR", reqId, error_code, error_message)
def stock_contract(symbol: str) -> Contract: """创建美股股票合约。""" contract = Contract() contract.symbol = symbol contract.secType = "STK" contract.exchange = "SMART" contract.currency = "USD" return contract
app = DepthApp()app.connect("127.0.0.1", 7497, clientId=974)threading.Thread(target=app.run, daemon=True).start()
if not app.ready.wait(10): raise RuntimeError("TWS API 连接超时,请检查 TWS API 设置和端口")
contract = stock_contract("AAPL")
app.reqMktDepth( 97401, # reqId:请求编号 contract, # contract:合约对象 5, # numRows:请求盘口档位数量 True, # isSmartDepth:是否请求 SMART 深度 [], # mktDepthOptions:普通请求传空列表)
time.sleep(8)app.cancelMktDepth(97401, True)app.disconnect()| 参数 | 中文解释 | 注意事项 |
|---|---|---|
reqId | 请求编号 | 回调和取消都用它关联 |
contract | 合约对象 | 必须能被 TWS 唯一识别;股票建议先用合约详情确认 conId 和交易所 |
numRows | 盘口档位数量 | 请求的档位数;如果市场深度小于该值,TWS 只会返回可用档位 |
isSmartDepth | 是否使用 SMART 深度 | True 请求 SMART 聚合深度;False 请求合约交易所对应深度 |
mktDepthOptions | 额外选项 | 普通请求传空列表 |
reqId 必须在同一个 API 客户端连接里保持唯一。后续的 updateMktDepth()、updateMktDepthL2() 和 cancelMktDepth() 都靠这个编号关联同一次订阅。
contract 建议不要只写 symbol。如果交易所或证券类型可能有歧义,先用 reqContractDetails() 查清楚,再请求二档行情。
numRows 不是“保证返回这么多档”,而是“最多请求这么多档”。实际返回数量取决于交易所、产品、行情权限和当时盘口。
isSmartDepth=True 适合美股 SMART 聚合深度;False 更接近指定交易所深度。如果收到权限错误,可以结合 reqMktDepthExchanges() 返回的 exchange、secType、serviceDataType 判断该订阅是否支持。
mktDepthOptions 是 TagValue 列表,普通 Python 示例传 []。如果官方针对某些交易所提供特殊选项,再按对应说明填写。
权限边界样例
Section titled “权限边界样例”请求 AAPL SMART 深度行情的参考结果:
CONNECTED=TrueDEPTH_ROWS=0DEPTH_L2_ROWS=0CANCEL_SENT=TrueERROR=reqId=97401;code=2152;msg=交易所 - 顶端: IBEOS; OVERNIGHT; 需要其它市场数据许可 - 深度: NASDAQ; BATS; ARCA; BEX; NYSE; IEX; ...错误信息列出了多个顶端行情和深度行情交易所,说明这不是 Python 代码格式错误,而是账户缺少相关市场数据许可。
先用 reqMktDepthExchanges() 看交易所能力,再用 reqContractDetails() 确认合约,最后再订阅二档行情。收到 2152 时,优先处理行情权限,而不是修改 clientId、端口或重装 API。