You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用IBApi reqWshEventData获取财报日期失败求助

问题排查与修复方案

问题根源拆解

你的脚本能正常连接TWS、拿到合约ID和WSH元数据,但就是触发不了wshEventData回调,主要问题出在这几个地方:

1. 请求参数不符合IB官方要求

IB文档明确规定,reqWshEventData不能只传conId或者只传过滤JSON,必须同时指定有效的conId和明确的过滤条件。你当前的两种请求方式都踩了坑:

  • 只传conId+空过滤:TWS不知道你要抓什么类型的事件数据,直接忽略请求
  • 只传过滤JSON+conId=0:没指定具体合约,TWS找不到对应的数据

2. 过滤JSON格式错误

你写的过滤条件有几个硬伤:

  • wsh_ed应该用布尔值true,不是字符串"true"
  • limit_region是无效字段,IB文档里根本没有这个参数
  • 没在过滤条件里关联目标合约,得用conids数组指定合约ID

3. 权限或TWS配置遗漏

  • 确认TWS/IB Gateway的API设置里,已经勾选了Allow WebSocket Socket Clients
  • 检查账户权限,部分账户类型可能没开放WSH事件数据的访问权限

修复后的完整代码

import json
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
import threading
import time


class IBApiApp(EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self, self)
        self.contract_id = None
        self.metadata_received = False
        self.event_data_received = False

    def nextValidId(self, orderId: int):
        print("已连接IBKR,正在请求合约详情...")
        self.request_contract_details()

    def error(self, reqId: int, errorCode: int, errorString: str, advancedOrderRejectJson=""):
        print(f"错误. ReqId: {reqId}, 代码: {errorCode}, 信息: {errorString}")

    def contractDetails(self, reqId, contractDetails):
        self.contract_id = contractDetails.contract.conId
        print(f"获取到合约ID (conId): {self.contract_id}")

    def contractDetailsEnd(self, reqId):
        if self.contract_id:
            print("合约ID获取成功,正在请求WSH元数据...")
            self.request_wsh_metadata()
        else:
            print("未获取到合约ID,请检查API设置和权限。")
            self.disconnect()

    def wshMetaData(self, reqId: int, data: str):
        print(f"收到WSH元数据 (请求ID {reqId}): {data}")
        self.metadata_received = True
        # 修复:同时传入conId和正确的过滤JSON
        self.request_wsh_event_data()

    def wshEventData(self, reqId: int, dataJson: str):
        print(f"收到WSH事件数据 (请求ID {reqId}): {dataJson}")
        self.event_data_received = True
        # 解析数据,提取财报日期
        data = json.loads(dataJson)
        if "events" in data:
            for event in data["events"]:
                if event.get("type") == "wshe_eps":
                    print(f"财报发布日期: {event.get('date')}")

    def request_contract_details(self):
        contract = Contract()
        contract.symbol = "TSLA"
        contract.secType = "STK"
        contract.exchange = "SMART"
        contract.currency = "USD"
        self.reqContractDetails(1, contract)

    def request_wsh_metadata(self):
        if self.contract_id:
            print("正在请求WSH元数据...")
            self.reqWshMetaData(1)
        else:
            print("合约ID未设置,无法请求WSH元数据。")

    def request_wsh_event_data(self):
        """修复:同时传入conId和正确的过滤JSON"""
        filter_json = json.dumps({
            "wsh_ed": True,  # 用布尔值,不是字符串
            "conids": [self.contract_id],  # 指定目标合约ID
            "event_type": {"wshe_eps": True}  # 明确要财报事件
        })

        print(f"请求WSH事件数据,过滤条件: {filter_json}")
        try:
            # 同时传有效的reqId、conId和过滤JSON
            self.reqWshEventData(2, self.contract_id, filter_json)
        except Exception as e:
            print(f"请求WSH事件数据出错: {e}")


def run_loop(app):
    app.run()


app = IBApiApp()
# 注意:端口要和你的TWS/IB Gateway匹配,paper账户TWS默认7497,IB Gateway默认4002
app.connect("127.0.0.1", 4001, clientId=1)

api_thread = threading.Thread(target=run_loop, args=(app,))
api_thread.start()

metadata_timeout = 30
event_data_timeout = 30
start_time = time.time()

while not app.metadata_received and time.time() - start_time < metadata_timeout:
    time.sleep(1)

if app.metadata_received:
    start_time = time.time()
    while not app.event_data_received and time.time() - start_time < event_data_timeout:
        time.sleep(1)
else:
    print("WSH元数据未在超时时间内收到。")

if app.event_data_received:
    print("WSH事件数据获取成功。")
else:
    print("WSH事件数据未找到或超时。")

app.disconnect()
api_thread.join()

额外注意点

  • 端口核对:确保连接的端口和你的TWS/IB Gateway配置一致,别连错了
  • 超时调整:财报数据可能有延迟,可适当调大event_data_timeout的数值
  • 错误排查:如果还是拿不到数据,仔细看error回调的错误码,IB官方文档有每个错误码的具体说明

内容的提问来源于stack exchange,提问作者m.eder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 13:27:01