Search code examples
pythonapiinteractive-brokers

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. 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".

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)

The helpdesk from IB refuses to answer my question: how do I either avoid this error message or suppress it? I don't know if it is something I'm doing wrong or if this is a bug on their API. As long as I can avoid this junk printed on my console, I will be OK. Any guidance is much appreciated.


Solution

  • I finally found an answer to this issue: you can see the solution below:

    https://groups.io/g/twsapi/message/43333

    It involves making a quick change on the connection.py file and re-installing TWS API. I left the answer posted here before in case someone wants to install an older version for some reason.