Streamlit and IBKR ib_insync error

Hello I am trying to display data that I am fetching from Interactive Brokers using ib_insync api.
I am running into some issues, from my troubleshooting and searches I believe it has something to do with asyncio.
I am running the code locally on my machine, ib_insync works well separately and I can print data. Python 3.9.6; streamlit==1.32.2

This is the error I get:

RuntimeError: There is no current event loop in thread ‘ScriptRunner.scriptThread’.

The problem is reported on github as well, somebody provided a solution but that does not work anymore.

from ib_insync import *
import streamlit as st

ib = IB()
ib.connect('127.0.0.1', 7497,clientId=1)
contract = Forex('EURUSD')
bars = ib.reqHistoricalData(
    contract, endDateTime='', durationStr='2 D',
    barSizeSetting='1 hour', whatToShow='MIDPOINT', useRTH=True)
df = util.df(bars)
st.dataframe(df)

Only requirements used are ib_insync and streamlit.

The I tried the solution from github and I get the exact same error:

from ib_insync import *
import asyncio
import streamlit as st
def get_or_create_eventloop():
    try:
        return asyncio.get_event_loop()
    except RuntimeError as ex:
        if "There is no current event loop in thread" in str(ex):
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            return asyncio.get_event_loop()

loop = get_or_create_eventloop()
asyncio.set_event_loop(loop)


ib = IB()
ib.connect('127.0.0.1', 7497,clientId=1)
contract = Crypto('BTC', 'PAXOS')
ib.qualifyContracts(contract)
bars = ib.reqHistoricalData(
    contract, endDateTime='', durationStr='2 D',
    barSizeSetting='1 hour', whatToShow='MIDPOINT', useRTH=True)
df = util.df(bars)
st.dataframe(df)

Hi @dreamless2871 and welcome to our community! :wave:

Just wondering - have you tried using st.cache_resource to manage the asyncio event loop and cache the async IB data fetching process?

Best,
Charly

Charly thank you for your response, I attempted your solution then made me realise by removing most of the lines of the code that it breaks just by importing both modules:

import streamlit as st
from ib_insync import *

Just having these 2 lines in my file breaks things.

I fixed the issue by importing modules in the following exact order:

import streamlit as st
import asyncio
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
from ib_insync import *

ib = IB()
ib.connect('127.0.0.1', 7497,clientId=1)
contract = Forex('EURUSD')
bars = ib.reqHistoricalData(
contract, endDateTime='', durationStr='2 D',
barSizeSetting='1 hour', whatToShow='MIDPOINT', useRTH=True)
df = util.df(bars)
print(df)
st.dataframe(df)
1 Like

Glad it fixed it! :hugs:

Best,
Charly

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.