erdewit / ib_insync

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

Ticks data overwrites IB time #494

Closed skestle closed 2 years ago

skestle commented 2 years ago

For some reason, the tick receiving messages in wrapper.py use the local time instead of the one provided by IB. This results in times that are incorrect by a combination of internet latency and machine time.

This will also offset with the bar data (which have their IB time respected).

Using the system clock as data should (in general) be done as a last resort when a data authority omits the time. Is there a reason why this was done this way? I'm guessing it's because of market depth data which has no time. In that case, I would choose honesty and remove time from the representation, instead being clear about receivedTime or even at some later point interpolatedTime which relates the system clock to received data and produces a roughly accurate local-based time.

A configuration option should be added to respect IB's tick time or (my preferred option):

See: https://github.com/erdewit/ib_insync/blob/c137917682bdbaf1a68017858930a4a38477bbee/ib_insync/wrapper.py#L744-L747 https://github.com/erdewit/ib_insync/blob/c137917682bdbaf1a68017858930a4a38477bbee/ib_insync/wrapper.py#L765 and https://github.com/erdewit/ib_insync/blob/c137917682bdbaf1a68017858930a4a38477bbee/ib_insync/wrapper.py#L898-L900

erdewit commented 2 years ago

For tick data and depth data there is no time information sent by IB. For tickByTick data the time is sent with 1 second resolution, which makes it useless in practical terms. Therefor the local arrival time is used for time-stamping the data. This timestamp is far too valuable to just remove it. It is the time that must be used in simulations, since you can only act when the data has reached you. In this regard the arrival time is much more useful to know than even the exact exchange time (which the IB time is not).

skestle commented 2 years ago

Ah! I hadn't noticed that the time was only seconds. Even the VB IB client has millis - how strange. Still, I'm intrigued by "the time that must be used in simulations", since this time is only available live, and will not correlate well if blended with historical (or even live bar) data. I'd also suggest that your simulations heavily depend on having a consistent latency which I find is not the case. I'd far prefer to simulate that in multiple internet scenarios. And if you're not simulating latency, how do your timestamps help? It's not as if orders are going to get to the exchange instantly, so how do you know what price you'd achieve??

Also, it's another edge case to code for when the system clock goes back in time and changes the chronology. For many years now, I've considered the local clock as inferior data, since it's not the authority (which in this IB case is also problematic)

And anybody can figure out what the time is now - I still want to know what time IB thinks it is so that I have more options going forward (e.g. being able to build the same bars off ticks or 5s bars would be nice)

In light of the precision issues, I'd change my request to adding ibTime to the objects to be able to see what IB thinks.

Or... on re-reading about tick and depth data not having any timing, I'd probably go for a time function which returns a time based on IB's time (tickByTick), or nothing (ticks and depth). This time function could then be modified to interpolate millis based on observed latency clues etc.

Anyhow, those are my thoughts for the moment...

skestle commented 1 year ago

Another note - if using Good Till Date (/Time) orders, then you're sending time commands to IB based on the local clock. This could affect short time frame orders, and also simulation of the same (due to the local time offset)