Need help with threading in function (ibapi)

Hi,

i try to use streamlit with the ibapi library to get some stock quotes.

This is my function:

def tws_hist(stock):
    class IBapi(EWrapper, EClient):
        def __init__(self):
            EClient.__init__(self, self)
            self.cols = ['date', 'open', 'high', 'low', 'close', 'volume']
            self.df = pd.DataFrame(columns=self.cols)
            self.data = []
        def historicalData(self, reqId:int, bar: BarData):
            self.data.append([bar.date, bar.open, bar.high, bar.low, bar.close, bar.volume])
        def error(self, reqId, errorCode, errorString):
            print("Error. Id: " , reqId, " Code: " , errorCode , " Msg: " , errorString)

    def run_loop():
        app.run()

    app = IBapi()
    today = dt.datetime.today().strftime("%Y%m%d %H:%M:%S")
    app.connect('127.0.0.1', 7496, 12)
    #Start the socket in a thread
    api_thread = threading.Thread(target=run_loop)#daemon=True)
    api_thread.start()
    time.sleep(1) #Sleep interval to allow time for connection to server
    #Create contract object
    contract = Contract()
    contract.symbol = stock
    contract.secType = 'STK'
    contract.exchange = 'SMART'
    contract.currency = 'USD'
    #Request Market Data
    app.reqMarketDataType(1)
    app.reqHistoricalData(1, contract, today, "6 M", "1 day", "TRADES", 0, 1, False, [])
    #time.sleep(1) #Sleep interval to allow time for incoming price data
    df = pd.DataFrame(app.data, columns=['Date', 'open', 'high', 'low', 'close', 'volume'])
    df['Date'] = pd.to_datetime(df['Date'], format='%Y%m%d')
    app.disconnect()
    return df

How do I get the dataframe out of the function?
At the moment it contains only the column names without values.

Thank you

Any ideas?

Or is it possible to call a external python script and work with the results?

Hi @mick76 -

Have you first tried returning app.data (without creating a dataframe) to see if it’s returning the data as you expect? The way you are constructiing the dataframe, it will create all of the columns, but if app.data is None or similar, there won’t be any data to parse.

Best,
Randy

app.data is empty if i call the function from streamlit

I’m not an expert on threading, but I suspect you need to do something like this example:

Best,
Randy

I’ve tried that too, but i am probably even less of an expert than you are. :grinning: