¿ªÔÆÌåÓý

ctrl + shift + ? for shortcuts
© 2025 Groups.io

Re: Tws Connection status monitoring


 
Edited

There we have it, Dave. Let me see whether I can put the pieces together for you:
  • The typical TWS API Python client is a two-thread solution.
  • EReader runs in its own thread, reads TWS/IBGW messages from the network socket connection, puts them into msg_queue, but does not perform any callbacks that relate TWS messages.
  • EClient and EWrapper run in the second thread. That thread not only processes your application logic but must also read messages from msg_queue and process the API callbacks.
  • When your code calls wait(120) in open_connection, all API callback processing stops, you don't get any of the error messages, nextValidId is never called, and your program is in dead lock

Your approach would work just fine in a three-thread approach where EWrapper and EClient run in two separate threads (plus a third thread for EReader). That is the typical TWS API Java setup and has the advantage that callback processing continues, even if the application thread is very busy or preoccupied with a long blocking operation (say spends time reading or writing a file, or god-forbid, does a sleep()).

Depending on your design preference you'd take one of two routes:
  • If you want to stay with the two-thread approach, take a look at what the IBKR Testbed/Program.py does. You'd basically define a "start" function as an entry point for your application code and call it at the end of the nextValidId function. No further synchronization is required since there is really only one thing going on at a time.
  • If you want to go with the three-thread approach, just start self.run() in a separate thread (see below). The consequence is, however, that there is more parallelism in your application (callbacks can now happen all the time) and you may need more synchronization amount the pieces.

I simply added this to your code and it worked right away:

??? def processTwsCallbacks(self):
??????? self.run()

??? def open_connection(self):
??????? self.connection_error = False
??????? self.event_nextValidId_callback.clear()
??????? self.connect("127.0.0.1", self.port, self.client_id)

??????? callbackThread = threading.Thread( target=self.processTwsCallbacks, daemon=True )
??????? callbackThread.start()


This is only a rough outline. Keep in mind that I am not a Python practitioner and that there may be more to the three-thread solution than just starting self.run() in a separate thread. But It will be the more performant solution and callbacks will be performed much more timely.

Hope this helps. I learned something new.
´³¨¹°ù²µ±ð²Ô

Join [email protected] to automatically receive all group messages.