IB API调用报错:TradingApp.error()缺失必填参数advancedOrderRejectJson
IB API重复运行报错问题解决
使用环境
- Python 3.1
- Spyder 5.4.2
- IB API 10.19
原始代码
from ibapi.client import EClient from ibapi.wrapper import EWrapper from ibapi.contract import Contract import threading import time class TradingApp(EWrapper, EClient): def __init__(self): EClient.__init__(self,self) def error(self, reqId, errorCode, errorString, advancedOrderRejectJson): print("Error {} {} {} {}".format(reqId,errorCode,errorString,advancedOrderRejectJson)) def contractDetails(self, reqId, contractDetails): print("redID: {}, contract:{}".format(reqId,contractDetails)) def websocket_con(): app.run() event.wait() #if event.is_set(): #app.close() event = threading.Event() app = TradingApp() app.connect("127.0.0.1", 4001, clientId=1) # starting a separate daemon thread to execute the websocket connection con_thread = threading.Thread(target=websocket_con) con_thread.start() time.sleep(1) # some latency added to ensure that the connection is established #creating object of the Contract class - will be used as a parameter for other function calls contract = Contract() contract.symbol = "AAPL" contract.secType = "STK" contract.currency = "USD" contract.exchange = "SMART" app.reqContractDetails(100, contract) # EClient function to request contract details time.sleep(5) # some latency added to ensure that the contract details request has been processed event.set()
问题现象
- 在Spyder的IPython控制台首次运行代码可成功,再次运行触发错误:
TypeError: TradingApp.error() missing 1 required positional argument: 'advancedOrderRejectJson' - 关闭IPython控制台后可再次运行,但第二次运行仍会失败
- 在终端直接运行代码则直接报错
- 注释掉
error函数后,仅关闭IPython控制台标签后能运行一次,再次运行会出现AttributeError: 'TradingApp' object has no attribute 'close'错误
解决方案
1. 修正error方法参数签名
IB API 10.19中EWrapper.error的标准定义里,advancedOrderRejectJson是可选参数(带默认值),你的实现没有设置默认值,导致回调时参数不匹配。修改error方法:
def error(self, reqId, errorCode, errorString, advancedOrderRejectJson=""): print("Error {} {} {} {}".format(reqId, errorCode, errorString, advancedOrderRejectJson))
2. 修复连接关闭与线程逻辑
EClient没有close方法,正确的关闭连接方式是调用disconnect()- 移除冗余的
threading.Event逻辑,简化线程管理:
修改后的websocket_con函数及后续代码:
def websocket_con(): app.run() # 创建实例前先清理可能存在的旧连接 try: app.disconnect() except NameError: pass app = TradingApp() app.connect("127.0.0.1", 4001, clientId=1) # 启动守护线程,程序结束时自动退出 con_thread = threading.Thread(target=websocket_con, daemon=True) con_thread.start() time.sleep(1) # 合约定义部分保持不变 contract = Contract() contract.symbol = "AAPL" contract.secType = "STK" contract.currency = "USD" contract.exchange = "SMART" app.reqContractDetails(100, contract) time.sleep(5) # 执行完请求后主动断开连接 app.disconnect()
3. Spyder环境特殊处理
Spyder的IPython控制台会保留全局变量和线程状态,重复运行时旧连接线程可能未销毁。除了代码里的清理逻辑,也可以每次运行前点击控制台的"重启内核"按钮,彻底清除残留状态。
内容的提问来源于stack exchange,提问作者jacob666
相关产品推荐
相关产品推荐

