跳转到内容

接收二档行情

二档行情请求成功后,TWS 会用两类回调推送盘口变化:updateMktDepth()updateMktDepthL2()

官方参考:Market Depth - Receiving

def updateMktDepth(self, reqId, position, operation, side, price, size):
"""接收普通二档盘口更新。"""
print(
reqId, # 请求编号
position, # 盘口位置,从 0 开始
operation, # 0=插入,1=更新,2=删除
side, # 0=卖方,1=买方
price, # 报价价格
size, # 报价数量
)

普通深度回调没有 marketMaker 字段,只能知道第几档、买卖方向、价格和数量。

def updateMktDepthL2(self, reqId, position, marketMaker, operation, side, price, size, isSmartDepth):
"""接收带 market maker / exchange 的二档盘口更新。"""
print(
reqId, # 请求编号
position, # 盘口位置,从 0 开始
marketMaker, # 做市商或交易所标识
operation, # 0=插入,1=更新,2=删除
side, # 0=卖方,1=买方
price, # 报价价格
size, # 报价数量
isSmartDepth, # 是否 SMART 深度
)

SMART 深度通常更依赖 updateMktDepthL2(),因为程序需要知道这一档来自哪个交易所或做市商标识。

字段中文解释开发注意
reqId请求编号reqMktDepth() 使用的编号一致
position盘口位置,从 0 开始不是自增序号,而是盘口列表里的位置
marketMaker做市商或交易所标识updateMktDepthL2() 有;SMART 深度里常用于区分来源
operation操作类型0 插入,1 更新,2 删除
side买卖方向0 卖方,1 买方
price报价价格删除操作时仍可能带价格,但应按 operation 处理
size报价数量股票数量通常是股数;不同产品需要结合合约单位理解
isSmartDepth是否 SMART 深度数据updateMktDepthL2()

二档行情不是简单追加日志。程序要按 positionoperationside 更新盘口快照:

操作处理方式
插入在对应方向的指定位置插入一档
更新修改指定位置的价格和数量
删除删除指定位置的一档

下面是一个最小盘口维护函数:

book = {"bid": [], "ask": []}
def apply_depth_update(position, operation, side, price, size, market_maker=None):
"""根据 TWS 推送的增量更新维护盘口快照。"""
levels = book["ask"] if side == 0 else book["bid"]
level = {"price": price, "size": size, "marketMaker": market_maker}
if operation == 0:
# 插入:在指定位置新增一档,后面的档位自动后移。
levels.insert(position, level)
elif operation == 1 and position < len(levels):
# 更新:替换指定位置的一档。
levels[position] = level
elif operation == 2 and position < len(levels):
# 删除:移除指定位置的一档。
levels.pop(position)

如果账户缺少二档行情权限,请求可能不会产生深度回调:

DEPTH_ROWS=0
DEPTH_L2_ROWS=0
ERROR=reqId=97401;code=2152;msg=交易所 - 顶端: IBEOS; OVERNIGHT; 需要其它市场数据许可 - 深度: NASDAQ; BATS; ARCA; BEX; NYSE; IEX; ...

实际开发时必须同时处理“有盘口更新”和“权限错误无更新”两种情况。