请求 IB 公告
reqNewsBulletins() 用来订阅 IB 公告。公告不是普通新闻行情,也不是订单通知,而是 IB 通过 TWS API 推送的系统公告或交易所可用性提示。
app.reqNewsBulletins(allMsgs)返回结果通过 updateNewsBulletin() 回调接收。
def reqNewsBulletins(self, allMsgs: bool): ...| 参数 | 中文含义 | 说明 |
|---|---|---|
allMsgs | 是否返回当天已有公告 | True 表示返回当天已有公告和新公告;False 表示只接收新公告 |
如果你只是做连通性验证,建议先用 True。这样如果当天有公告,更容易收到历史公告回调。
注意:allMsgs=True 不代表一定会收到回调。当天没有公告、会话没有可见公告或公告源没有推送时,回调行数可能是 0。
连接 TWS / IB Gateway -> 等待 nextValidId() -> reqNewsBulletins(True) -> updateNewsBulletin(...) -> cancelNewsBulletins()公告接口是订阅型接口,不需要 reqId。取消时也不传请求编号。
Python 请求示例
Section titled “Python 请求示例”import threading
from ibapi.client import EClientfrom ibapi.wrapper import EWrapper
INFO_CODES = {2103, 2104, 2105, 2106, 2107, 2108, 2158}
class RequestBulletinsApp(EWrapper, EClient): def __init__(self): EClient.__init__(self, self) self.ready = threading.Event() self.bulletin_ready = threading.Event() self.rows = [] self.info_codes = [] self.errors_seen = []
def nextValidId(self, orderId): self.ready.set()
def updateNewsBulletin(self, msgId, msgType, newsMessage, originExch): self.rows.append({ "msgId": msgId, "msgType": msgType, "messageLength": len(newsMessage or ""), "originExchange": originExch or "EMPTY", }) self.bulletin_ready.set()
def error(self, reqId, errorTime, errorCode, errorString, advancedOrderRejectJson=""): if errorCode in INFO_CODES: self.info_codes.append(errorCode) else: self.errors_seen.append((reqId, errorCode, errorString))
app = RequestBulletinsApp()
try: app.connect("127.0.0.1", 7497, clientId=130) thread = threading.Thread(target=app.run, daemon=True) thread.start()
if not app.ready.wait(8): raise RuntimeError("等待 nextValidId 超时")
app.reqNewsBulletins(True) callback_received = app.bulletin_ready.wait(6)
finally: if app.isConnected(): app.cancelNewsBulletins() app.disconnect()
print("ALL_MSGS=True")print("REQUEST_SENT=True")print(f"BULLETIN_CALLBACK_RECEIVED={callback_received}")print(f"BULLETIN_ROW_COUNT={len(app.rows)}")print("INFO_CODES=" + (",".join(map(str, sorted(set(app.info_codes)))) if app.info_codes else "NONE"))print(f"NON_INFO_ERROR_COUNT={len(app.errors_seen)}")CONNECTED=TrueALL_MSGS=TrueREQUEST_SENT=TrueBULLETIN_CALLBACK_RECEIVED=FalseBULLETIN_ROW_COUNT=0MSG_TYPE_COUNTS=NONEORIGIN_EXCH_COUNTS=NONEMESSAGE_LENGTHS=EMPTYCANCEL_SENT=TrueROWS_BEFORE_CANCEL=0ROWS_AFTER_CANCEL_WAIT=0INFO_CODES=2104,2106,2158NON_INFO_ERROR_COUNT=0IS_CONNECTED_AFTER_DISCONNECT=False这组输出表示请求成功,但等待期间没有收到公告。这是正常边界:当天没有可用公告,或者会话没有新的公告时,回调行数可能是 0。请求后仍然应调用 cancelNewsBulletins(),让程序状态保持清楚。
没有公告回调是不是失败?
Section titled “没有公告回调是不是失败?”不一定。公告不是固定会返回的数据源。判断请求链路是否异常,要结合连接状态、错误码和是否成功取消订阅。
allMsgs=True 会返回所有历史公告吗?
Section titled “allMsgs=True 会返回所有历史公告吗?”不会。官方说明它返回当天已有公告和新的公告,不是长期历史公告查询。
这个接口能替代新闻接口吗?
Section titled “这个接口能替代新闻接口吗?”不能。普通新闻标题、新闻文章和新闻提供商属于 News 目录下的接口,不是 Bulletins。