跳转到内容

市场扫描器订阅总览

市场扫描器订阅用于让 TWS 按指定条件返回一组排名后的合约。它常用于发现标的,例如成交量活跃股票、涨幅榜、最活跃期货、期权成交量异常等。

它和普通行情接口的区别是:扫描器先帮你找“哪些合约符合条件”,但不负责持续推送这些合约的最新价、买卖盘或 K 线。拿到合约后,如果还要行情,需要再调用 reqMktData()reqHistoricalData() 等接口。

官方参考:IBKR Campus - Market Scanner Subscription

步骤接口 / 回调说明
1ScannerSubscription()创建扫描订阅对象。
2设置字段填写 instrumentlocationCodescanCode 等条件。
3reqScannerSubscription()向 TWS 发起扫描订阅。
4scannerData()接收每一条排名结果。
5scannerDataEnd()本轮扫描结果结束。
6cancelScannerSubscription()不再需要结果时取消订阅。
限制说明
单个扫描规则最多返回 50 条即使市场里有更多标的符合条件,API 也不会一次返回无限结果。
最多同时 10 个 API 扫描多个页面或多个策略共享这类限制,应该及时取消不用的订阅。
扫描结果不含行情字段scannerData() 返回合约列表,不返回 bid、ask、last、volume。
过滤条件可能依赖行情权限只拿合约列表通常不等于请求实时行情,但价格、成交量、市值等过滤可能需要对应市场数据权限。

如果某个扫描组合在 API 里一直返回空结果,建议先在 TWS 的 Advanced Market Scanner / 高级市场扫描器中用同样的产品、地区、扫描规则和过滤条件建一次。界面里也建不出来的组合,API 里通常也不会稳定返回。

from ibapi.scanner import ScannerSubscription
def hot_us_stocks_by_volume() -> ScannerSubscription:
"""扫描美国主要市场中成交量活跃、价格大于 5 美元的股票。"""
subscription = ScannerSubscription()
subscription.numberOfRows = 5
subscription.instrument = "STK"
subscription.locationCode = "STK.US.MAJOR"
subscription.scanCode = "HOT_BY_VOLUME"
subscription.abovePrice = 5
subscription.aboveVolume = 100_000
return subscription
字段中文说明
numberOfRows返回多少条结果。新手建议先用较小值,例如 510
instrument扫描产品类型,STK 表示股票。
locationCode扫描范围,STK.US.MAJOR 表示美国主要股票市场。
scanCode扫描规则,HOT_BY_VOLUME 表示成交量活跃。
abovePrice最低价格过滤。
aboveVolume最低成交量过滤。
SUBSCRIPTION=numberOfRows=5;instrument=STK;locationCode=STK.US.MAJOR;scanCode=HOT_BY_VOLUME;abovePrice=5;aboveVolume=100000
SCAN_END=True
SCAN_ROWS=5
SCAN=reqId=98001;rank=0;symbol=PEMX;secType=STK;exchange=SMART;currency=USD;conId=631370177
SCAN=reqId=98001;rank=1;symbol=UBXG;secType=STK;exchange=SMART;currency=USD;conId=885295404
SCAN=reqId=98001;rank=2;symbol=SPCL;secType=STK;exchange=SMART;currency=USD;conId=871422657
SCAN=reqId=98001;rank=3;symbol=GRAF;secType=STK;exchange=SMART;currency=USD;conId=722498821
SCAN=reqId=98001;rank=4;symbol=CFIT;secType=STK;exchange=SMART;currency=USD;conId=771754279
ERROR=reqId=98001;code=162;msg=历史市场数据服务错误消息:API scanner subscription cancelled: 98001

扫描器结果会随市场状态变化,股票代码不保证和示例完全一致。你应该依赖字段结构,而不是依赖某次示例中的具体排名。

扫描器通常比实时行情更容易跑通,但仍可能受账户权限、产品范围和交易时段影响。如果扫描条件太窄,scannerDataEnd() 可能会返回但没有任何 scannerData() 行。

如果取消订阅后看到类似“scanner subscription cancelled”的错误提示,通常表示取消动作已经生效,不代表扫描失败。