开云体育

ctrl + shift + ? for shortcuts
© 2025 开云体育

reqCurrentTimeAsync() mystery


 

I am having some very strange problems with reqCurrentime().

Look at the below script, which simply gets the current time and the remote time, compares them, waits for a little bit, and then tries again.

async def main2():
    N = 300
    times = np.zeros(N)
    ib = ibs.IB()
    await ib.connectAsync("gateway", 4004, clientId=20, timeout=60)

    for i in range(300):
        local_tm = datetime.datetime.now(datetime.UTC)
        try:
            server_tm = await asyncio.wait_for(ib.reqCurrentTimeAsync(), 10.0)
        except TimeoutError:
            print(f"{i} :Timeout!")
            times[i] = 1.0
        else:
            times[i] = (server_tm - local_tm).total_seconds()
        t2 = datetime.datetime.now(datetime.UTC)
        processing = (t2 - local_tm).total_seconds()
        await asyncio.sleep(0.5)
        print(f"{i} : diff = {times[i]:.2f} sec, processing = {processing:.2f} sec")

    print(f"Avg = {np.mean(times)}, std = {np.std(times)}")

asyncio.run(main2())

The strange thing here is that if I await asyncio.sleep(1) or longer, the program works more or less as expected. Below is an example of such normal output:

0 : diff = -0.88 sec, processing = 0.00 sec
1 : diff = -0.88 sec, processing = 0.00 sec
2 : diff = -0.88 sec, processing = 0.00 sec
3 : diff = -0.88 sec, processing = 0.00 sec
4 : diff = -0.89 sec, processing = 0.00 sec
5 : diff = -0.89 sec, processing = 0.00 sec
6 : diff = -0.89 sec, processing = 0.00 sec

However, once I await asyncio.sleep(0.5) or anything below 1, I see something as follows:

0 : diff = -0.94 sec, processing = 0.00 sec
1 :Timeout!
1 : diff = 1.00 sec, processing = 10.01 sec
2 : diff = -0.95 sec, processing = 0.00 sec
3 :Timeout!
3 : diff = 1.00 sec, processing = 10.01 sec
4 : diff = -0.97 sec, processing = 0.00 sec
5 :Timeout!
5 : diff = 1.00 sec, processing = 10.01 sec
6 : diff = -0.98 sec, processing = 0.00 sec
7 :Timeout!
7 : diff = 1.00 sec, processing = 10.01 sec
8 : diff = -1.00 sec, processing = 0.00 sec

In other words, reqCurrentTimeAsync() times out every other time, even though I have set the timeout to be 10 seconds! If I wait for 0.5 second between each call of reqCurrentTime(), I am only sending 2 messages per second.

(I was debugging some strange freezing up in production and finally produced this minimal example to reproduce the problem.)

Does anything know what might be going on?


 

Although I can't find it in the document, I believe IB may has restrictions no to have two calls within a second, similar to this:


 

This did bit me a few years ago, this was a change by IB about the semantics for reqCurrentTime().? For unknown reasons, IB decided that if you requested the time more than once in the same second to TWS or the gateway, there would be *no* answer provided at all.? The IB own python binding solves that by maintaining a local copy of the time, so reqCurrentTime() is not forwarded to TWS (or the gateway) twice per second.
?
Not responding at all is highly problematic, some of my ib_insync() code started to fully hang depending on when exactly call to reqCurrentTime() were done.? I did correspond with Ewald at the time, but he considered that a brain dead decision by IB (I concur on that) and did not want to code some caching solution similar to IB code (I am less sure about that).? You can modify the library code on your own, or simply make sure that you never call reqCurrentTime() too fast.? I follow the second approach in my own code.
?
You must ask yourself who in his right mind will add code to explicitly check the amount of time between requests, then not answering at all if that happens, not even an error, instead of the previous behavior where you simply always return the current time.? I think this is the only case where a request is not associated with a response in the whole API.


 

I added some code so that my code calls reqCurrentTimeAsync every few seconds. I use it to make sure the network is properly connected, so this should be fine.

Yeah, my code was locking up periodically and it took me a while to realize that it was because sometimes reqCurrentTimeAsync never received a response.