ib-api-reloaded / ib_async

Python sync/async framework for Interactive Brokers API (replaces ib_insync)
BSD 2-Clause "Simplified" License
467 stars 73 forks source link

add fast mode #28

Closed eyalk11 closed 5 months ago

eyalk11 commented 5 months ago

Optionally don't do all the reqs at start. They are mostly not needed (where i am just use it to communicate with ib in a complex app) and take time.

It is by on default in this commit, but easy to change.

mattsta commented 5 months ago

Thanks!

Potentially interesting if people don't care about live details and only want to send commands.

I'll look at getting this flag added. I'll probably rename fast to something more descriptive like skipAccountDetails or maybe add a couple other flags for skipping individual components directly.

This is also a nice place to fix a bug I've always had but never looked into. It fetches all executions on initial connection, but it also fires the execution handler for each old execution being loaded, so if you do a simple restart, you can trigger dozens or hundreds of expired execution handler events on startup which has always seemed wrong (in my other system I just added a global flag for "if startup is not complete yet, ignore any executions being reported because they aren't real").

mattsta commented 5 months ago

Looking at adapting this now.

How about some extra startup flags where they default to ALL but you can remove parts as needed:

class StartupFetch(Flag): 
    POSITIONS = auto()                                                                    
    ORDERS_OPEN = auto()                                                                  
    ORDERS_COMPLETE = auto()                                                              
    ACCOUNT_UPDATES = auto()                                                              
    SUB_ACCOUNT_UPDATES = auto()                                                          
    EXECUTIONS = auto()                                                                   

StartupFetchNONE = StartupFetch(0)

StartupFetchALL = (                                                                       
    StartupFetch.POSITIONS                                                                
    | StartupFetch.ORDERS_OPEN                                                            
    | StartupFetch.ORDERS_COMPLETE                                                        
    | StartupFetch.ACCOUNT_UPDATES                                                        
    | StartupFetch.SUB_ACCOUNT_UPDATES                                                    
    | StartupFetch.EXECUTIONS                                                             
) 

Then to ignore all the auto-loading on startup, you would use StartupFetchNONE in:

connectAsync(host, port, clientId, fetchFields = ib_async.ib.StartupFetchNONE)

or to just use ALL but remove one field, you could do:

fetchFields = ib_async.ib.StartupFetchALL & ~ib_async.ib.StartupFetch.EXECUTIONS

(use all with EXECUTIONS removed).

These are of course for more specific use cases for advanced users. The main benefit of the ib_insync/async pattern is all your data is loaded up front and sync automatically, but this breaks some of the auto-loading guarantees.