erdewit / ib_insync

Python sync/async framework for Interactive Brokers API
BSD 2-Clause "Simplified" License
2.8k stars 744 forks source link

Curious how to do concurrency around ib_insync #253

Closed kootenpv closed 4 years ago

kootenpv commented 4 years ago

Thanks a lot for the wonderful package, it's been so nice coming from ibapi.

I am wondering how I can do concurrency around it. While I like that even though it is using asyncio, I can use it in a synchronous manner, the following cases are not obvious to me. I realize this is probably just me and not an ib_insync issue! But maybe it can be helpful if you shed some light for some use cases.

I did notice the Qt and Tk apps, but I felt like the code there is specific to those frameworks.

So here is my situation:

I want to follow some news (using e.g. python requests) and then at the right moment, buy.

  1. How is it possible to use threads? It seems to have an issue with that it cannot use the event loop in the thread?

  2. In case I want to use asyncio: I want other coroutines to work but ib.sleep is synchronous, how would that work? Or should I just not use ib.sleep in that case and use asyncio.sleep instead and it will work?

  3. I am even curious to how to use this as part of e.g. Flask or FastAPI.

txu2014 commented 4 years ago

I think FastAPI would be a solution. see https://github.com/erdewit/ib_insync/issues/251

kootenpv commented 4 years ago

Looks good thanks. Though I wonder, that looks like for each request it has to reestablish the connection with the websocket?

drusakov778 commented 4 years ago

-> https://groups.io/g/insync

erdewit commented 4 years ago

My opinionated suggestion is to not use threads and use asyncio-native libraries throughout. That means instead of requests to use for example aiohttp, instead of Flask to use FastAPI/ sanic /quart/etc, and likewise for web servers, database clients etc. This makes the whole concurrency problem so much easier like you wouldn't believe it.

And yes, when in a coroutine use await asyncio.sleep(...).

kootenpv commented 4 years ago

Sorry to bother you with this! I don't mean to be stubborn but I'm just concerned with asyncio (I had major headaches with it in the past and lost money), but I understand and value your perspective.

I had a look at ib.sleep, and it's run method within.

Question: When I'm using threads I could actually use asyncio.run(asyncio.sleep(0.2))? If I understand it correctly this would also allow ib_insync to progress with work? Or am I missing something extra that ib.sleep does?

erdewit commented 4 years ago

ib.sleep starts the event loop and the loop must not be already running at that point. With asyncio.sleep it's the other way around, it yields to the already running event loop.

If you want to run ib_insync in it's own thread then that thread needs to have it's own event loop.