跳转到内容

请求市场扫描器参数

reqScannerParameters() 用来请求市场扫描器的可用参数。这个接口不需要传 reqId,因为 TWS 只会通过 scannerParameters(xml) 回调返回一份 XML。

它通常在程序启动、配置页面打开,或者需要刷新扫描器选项时调用。不要在高频循环里反复请求,因为 XML 很大,解析也需要时间。

官方参考:IBKR Campus - Request Market Scanner Parameters

app.reqScannerParameters()

调用前必须已经完成 TWS 连接,并收到 nextValidId() 或确认连接就绪。

from __future__ import annotations
import threading
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
class ScannerParametersApp(EWrapper, EClient):
def __init__(self) -> None:
EClient.__init__(self, self)
self.ready = threading.Event()
self.done = threading.Event()
self.xml = ""
def nextValidId(self, orderId: int) -> None:
# 收到 nextValidId 后,说明 socket 连接和基础握手已经完成。
self.ready.set()
def scannerParameters(self, xml: str) -> None:
# TWS 会把可用扫描器参数一次性放在 xml 字符串里返回。
self.xml = xml
self.done.set()
app = ScannerParametersApp()
app.connect("127.0.0.1", 7497, clientId=98000)
thread = threading.Thread(target=app.run, daemon=True)
thread.start()
if app.ready.wait(10):
app.reqScannerParameters()
if app.done.wait(10):
print("收到扫描器参数 XML,长度:", len(app.xml))
app.disconnect()
项目中文说明
reqScannerParameters()请求市场扫描器参数 XML。
scannerParameters(xml)接收 TWS 返回的 XML 字符串。
xml描述可用 instrumentlocationCodescanCode 等配置的 XML。
clientIdAPI 客户端编号,和其它连接保持不同即可。

reqScannerParameters() 本身没有 reqId,因此如果程序里同时有多个模块调用它,应在应用层控制调用时机,避免重复解析同一份大型 XML。

CONNECTED=True
PARAMETERS_RECEIVED=True
PARAMETERS_XML_LENGTH=1963553
PARAMETERS_ROOT=ScanParameterResponse
INSTRUMENT_COUNT=784
LOCATION_COUNT=321
SCAN_CODE_COUNT=771

如果 PARAMETERS_RECEIVED=False,先检查 TWS 是否登录、API 是否启用、端口是否正确,以及客户端是否真的进入 app.run() 事件循环。

场景建议
程序启动可以调用一次,缓存可用字段。
用户打开扫描器配置页可以刷新一次,确保字段和 TWS 版本一致。
用户每次点扫描按钮不建议每次都请求 XML,扫描按钮应该直接使用已选参数。
TWS 升级后建议重新读取,避免旧字段已经变化。

XML 体积较大,拿到后可以只保存需要的字段,例如产品类型、市场范围、扫描规则和过滤条件代码。