[英]How to eliminate (or suppress from console) Interactive Brokers error when downloading data with Python API
I wrote the code below to read information from my accounts at Interactive Brokers:我编写了下面的代码来从我在盈透证券的账户中读取信息:
# Interactive Brokers functions to import data
def read_positions(): #read all accounts positions and return DataFrame with information
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.common import TickerId
import pandas as pd
class ib_class(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
self.all_positions = pd.DataFrame([], columns = ['Account','Symbol', 'Quantity', 'Average Cost'])
def position(self, account, contract, pos, avgCost):
index = str(account)+str(contract.symbol)
self.all_positions.loc[index]=account,contract.symbol,pos,avgCost
def error(self, reqId:TickerId, errorCode:int, errorString:str):
if reqId > -1:
print("Error. Id: " , reqId, " Code: " , errorCode , " Msg: " , errorString)
def positionEnd(self):
super().positionEnd()
self.disconnect()
ib_api = ib_class()
ib_api.connect("127.0.0.1", 7496, 0)
ib_api.reqPositions()
current_positions = ib_api.all_positions
ib_api.run()
return(current_positions)
def read_navs(): #read all accounts NAVs
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.common import TickerId
import pandas as pd
class ib_class(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
self.all_accounts = pd.DataFrame([], columns = ['reqId','Account', 'Tag', 'Value' , 'Currency'])
def accountSummary(self, reqId, account, tag, value, currency):
if tag == 'NetLiquidationByCurrency':
index = str(account)
self.all_accounts.loc[index]=reqId, account, tag, value, currency
def error(self, reqId:TickerId, errorCode:int, errorString:str):
if reqId > -1:
print("Error. Id: " , reqId, " Code: " , errorCode , " Msg: " , errorString)
def accountSummaryEnd(self, reqId:int):
super().accountSummaryEnd(reqId)
self.disconnect()
ib_api = ib_class()
ib_api.connect("127.0.0.1", 7496, 0)
ib_api.reqAccountSummary(9001,"All","$LEDGER")
current_nav = ib_api.all_accounts
ib_api.run()
return(current_nav)
If I call the two functions read_positions()
or read_navs()
I get the results I want, on DataFrame variables.如果我调用两个函数
read_positions()
或read_navs()
我会在 DataFrame 变量上得到我想要的结果。 However, I get an error message (on the console) that reads:但是,我收到一条错误消息(在控制台上),内容如下:
"OSError: [WinError 10038] An operation was attempted on something that is not a socket".
“OSError: [WinError 10038] 试图对不是套接字的东西进行操作”。
Before the error message itself, I get a lot of error-related messages:在错误消息本身之前,我收到了很多与错误相关的消息:
unhandled exception in EReader thread Traceback (most recent call last): File "C:\\Users\\xxxxx\\Anaconda3\\lib\\site-packages\\ibapi-9.76.1-py3.7.egg\\ibapi\\reader.py", line 34, in run data = self.conn.recvMsg() File "C:\\Users\\xxxxx\\Anaconda3\\lib\\site-packages\\ibapi-9.76.1-py3.7.egg\\ibapi\\connection.py", line 99, in recvMsg buf = self._recvAllMsg() File "C:\\Users\\xxxxx\\Anaconda3\\lib\\site-packages\\ibapi-9.76.1-py3.7.egg\\ibapi\\connection.py", line 119, in _recvAllMsg buf = self.socket.recv(4096)
EReader 线程 Traceback 中未处理的异常(最近一次调用最后一次):文件“C:\\Users\\xxxxx\\Anaconda3\\lib\\site-packages\\ibapi-9.76.1-py3.7.egg\\ibapi\\reader.py”,行34、在运行data = self.conn.recvMsg()文件“C:\\Users\\xxxxx\\Anaconda3\\lib\\site-packages\\ibapi-9.76.1-py3.7.egg\\ibapi\\connection.py”,行99、在recvMsg buf = self._recvAllMsg()文件“C:\\Users\\xxxxx\\Anaconda3\\lib\\site-packages\\ibapi-9.76.1-py3.7.egg\\ibapi\\connection.py”,第119行,在 _recvAllMsg buf = self.socket.recv(4096)
The helpdesk from IB refuses to answer my question: how do I either avoid this error message or suppress it? IB 的帮助台拒绝回答我的问题:我该如何避免或抑制此错误消息? I don't know if it is something I'm doing wrong or if this is a bug on their API.
我不知道这是我做错了什么,还是他们 API 上的错误。 As long as I can avoid this junk printed on my console, I will be OK.
只要我能避免在我的控制台上打印这些垃圾,我就可以了。 Any guidance is much appreciated.
非常感谢任何指导。
I had a similar problem with the 9.76.01 API, so I went back to 9.74.01, which doesn't have this issue.我在 9.76.01 API 上遇到了类似的问题,所以我回到了 9.74.01,它没有这个问题。
I tried to suppress the error with try/catch blocks, but I never got that to work.我试图用 try/catch 块来抑制错误,但我从来没有让它起作用。
Matt Scarpino马特·斯卡皮诺
Algorithmic Trading with Interactive Brokers与盈透证券的算法交易
Matt's answer above is correct: it was an API bug! Matt 上面的回答是正确的:这是一个 API 错误! I'm only adding this answer to provide more clear steps on how to downgrade to the older version:
我只是添加此答案以提供有关如何降级到旧版本的更清晰的步骤:
1) Download the older version from here: http://interactivebrokers.github.io/downloads/TWS%20API%20Install%20974.01.msi 1) 从这里下载旧版本: http : //interactivebrokers.github.io/downloads/TWS%20API%20Install%20974.01.msi
IB doesn't show the links for older versions but they keep the file on the Github (note the version name at the end of the link address) IB 不显示旧版本的链接,但他们将文件保存在 Github 上(注意链接地址末尾的版本名称)
2) Uninstall the current version. 2) 卸载当前版本。 From IB's own website, do the following:
在 IB 自己的网站上,执行以下操作:
3) Install the API using the .msi file 3) 使用 .msi 文件安装 API
4) Run the Anaconda prompt and navigate to the dir C:\\TWS API\\source\\pythonclient 4) 运行 Anaconda 提示符并导航到目录 C:\\TWS API\\source\\pythonclient
5) Run: "python setup.py install" 5)运行:“python setup.py install”
6) After python setup.py install, restart Spyder (if it was opened; I closed mine before step #5 above) 6)安装python setup.py后,重启Spyder(如果它已经打开;我在上面的步骤#5之前关闭了我的)
After I installed this older version, the error disappeared!我安装这个旧版本后,错误消失了!
So instead of downgrading, I found a quick fix to suppressing the error message.因此,我没有降级,而是找到了抑制错误消息的快速修复方法。 Go to the script where its messing up at, it should be connection.py and at line 119 at the very bottom.
转到它搞砸的脚本,它应该是 connection.py 和最底部的第 119 行。 This is what I did to catch the error and it worked.
这就是我为捕获错误所做的工作并且它起作用了。
while cont and self.socket is not None:
try:
buf = self.socket.recv(4096)
allbuf += buf
logger.debug("len %d raw:%s|", len(buf), buf)
if len(buf) < 4096:
cont = False
except OSError:
pass
I was able to silence the error, however I am not sure whether this fix breaks anything else.我能够消除错误,但是我不确定此修复程序是否会破坏其他任何内容。 Maybe someone who has an in-depth understanding of the API code can tell us whether this is ok.
也许对API代码有深入了解的人可以告诉我们这是否可以。
In connection.py在连接.py
def _recvAllMsg(self):
cont = True
allbuf = b""
while cont and self.socket is not None:
try: #this line added
buf = self.socket.recv(4096)
except OSError: #this line added
buf = b'' #this line added
allbuf += buf
logger.debug("len %d raw:%s|", len(buf), buf)
if len(buf) < 4096:
cont = False
return allbuf
I finally found an answer to this issue: you can see the solution below:我终于找到了这个问题的答案:你可以看到下面的解决方案:
https://groups.io/g/twsapi/message/43333 https://groups.io/g/twsapi/message/43333
It involves making a quick change on the connection.py file and re-installing TWS API.它涉及对 connection.py 文件进行快速更改并重新安装 TWS API。 I left the answer posted here before in case someone wants to install an older version for some reason.
我之前在这里留下了答案,以防有人出于某种原因想要安装旧版本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.