跳转到内容

接收市场扫描器结果

scannerData() 是市场扫描器每一条结果的回调。一次扫描通常会返回多条 scannerData(),最后用 scannerDataEnd() 表示本轮结果结束。

扫描器返回的是“符合条件的合约列表”,不是价格行情。最重要的字段通常是 rankcontractDetails.contract.symbolcontractDetails.contract.conId

官方参考:IBKR Campus - Receive Market Scanner Subscription

def scannerData(
self,
reqId: int,
rank: int,
contractDetails,
distance: str,
benchmark: str,
projection: str,
legsStr: str,
) -> None:
...
字段中文说明
reqId请求编号,用来区分是哪一个扫描订阅返回的数据。
rank结果排名,从 0 开始。
contractDetails合约详情对象,里面包含 contract、交易类别、最小价格变动等信息。
distanceIBKR 保留字段,部分扫描类型可能返回距离或排序辅助信息。
benchmarkIBKR 保留字段,部分扫描类型可能返回基准信息。
projectionIBKR 保留字段,部分扫描类型可能返回投影信息。
legsStr组合腿信息,主要用于 EFP 或组合类扫描。

distancebenchmarkprojectionlegsStr 经常为空字符串,这是正常现象。不要因为这些字段为空就丢弃结果,核心合约信息通常在 contractDetails.contract 里。

def scannerData(self, reqId, rank, contractDetails, distance, benchmark, projection, legsStr) -> None:
contract = contractDetails.contract
print({
"排名": rank,
"代码": contract.symbol,
"证券类型": contract.secType,
"交易所": contract.exchange,
"货币": contract.currency,
"合约ID": contract.conId,
})

拿到 conId 后,后续可以更稳定地请求行情或历史数据,因为 conId 比单纯的 symbol 更明确。

SCAN=reqId=98001;rank=0;symbol=PEMX;secType=STK;exchange=SMART;currency=USD;conId=631370177;distance=;benchmark=;projection=
SCAN=reqId=98001;rank=1;symbol=UBXG;secType=STK;exchange=SMART;currency=USD;conId=885295404;distance=;benchmark=;projection=
SCAN=reqId=98001;rank=2;symbol=SPCL;secType=STK;exchange=SMART;currency=USD;conId=871422657;distance=;benchmark=;projection=
SCAN=reqId=98001;rank=3;symbol=GRAF;secType=STK;exchange=SMART;currency=USD;conId=722498821;distance=;benchmark=;projection=
SCAN=reqId=98001;rank=4;symbol=CFIT;secType=STK;exchange=SMART;currency=USD;conId=771754279;distance=;benchmark=;projection=

这些结果来自一次实际扫描,具体代码和排名会随时间变化。写程序时应该按字段处理,不要把示例里的股票代码写死。

def scannerDataEnd(self, reqId: int) -> None:
print("扫描器结果结束:", reqId)

scannerDataEnd() 到达后,说明这一轮结果已经发完。它不表示订阅永久结束;如果你不再需要更新,应主动调用 cancelScannerSubscription(reqId)

扫描器不会在 scannerData() 里返回以下行情字段:

你可能想要的字段应该再调用什么
最新价、买价、卖价reqMktData()
历史 K 线reqHistoricalData()
逐笔成交reqTickByTickData()
合约更完整资料reqContractDetails()

也就是说,扫描器适合做“发现标的”,后续行情和交易逻辑应该用其它接口继续处理。

场景建议
返回多条结果rank 排序展示。
返回 0 条结果放宽过滤条件,或换一个 scanCode / locationCode
想拿实时价格对返回的合约再调用 reqMktData()
想拿历史 K 线对返回的合约再调用 reqHistoricalData()