erdewit / ib_insync

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

Partial share amounts missing from Fill item executions #558

Closed snielsen-sgiam closed 1 year ago

snielsen-sgiam commented 1 year ago

When examining fillItems from ib.fills(), the 'shares' and 'cumQty' fields appear to be rounded.

For instance, when we make a buy for 1.1404 shares, it comes through as two fillItems, one with a quantity of 1.0 and another with a quantity of 0.0.

I've also written code to get the fill data using the 'ibapi' module and it correctly returns a fill entry of 1.0 share and another fill entry of 0.140400 shares.

erdewit commented 1 year ago

These Execution fields are treated as floats and are not rounded by ib_insync. Unless a very old version is used from back when they were ints.

snielsen-sgiam commented 1 year ago

pip freeze reports ib-insync==0.9.81

If it's not a rounding issue, then perhaps this should be re-titled "Partial share amounts missing from Fill item executions".

erdewit commented 1 year ago

What you see is the data as IB is sending it.

snielsen-sgiam commented 1 year ago

Do ibapi and ib_insync use different mechanisms? When I use ibapi I correctly get partial share values back. Why would TWS send ib_insync 0.0 and ibapi 0.140400?

erdewit commented 1 year ago

You can use the IB gateway and turn on traffic logging to see what is sent and if there are any differences.

snielsen-sgiam commented 1 year ago

The trade in question happened yesterday and I couldn't figure out how to get IB Gateway to return data on fills from yesterday, but I did figure out how to create API logs from TWS and I was able to find the API lines in question. Somehow it looks like the way that ibapi and ib_insyc ask for fill data from the API is different because it is indeed getting different results:

Response when ib_insyc asks:

09:50:17:405 -> ---Ö11-3944-0-414366114-AON-STK--0.0---IBKR-USD-AON--000102df.63ebb964.01.01-20230214 08:05:58 America/Los_Angeles-U7956461-IBKR-BOT-0-318.35-770419765-0-0-1-318.279849-Trades-Top 50 rebalance-ibkr-2023-02-14.csv----2-

Response when ibapi asks:

09:51:28:261 -> ---Î11-10001-0-414366114-AON-STK--0.0---IBKR-USD-AON--000102df.63ebb964.01.01-20230214 08:05:58-U7956461-IBKR-BOT-0.1404-318.35-770419765-0-0-1.1404-318.279849-Trades-Top 50 rebalance-ibkr-2023-02-14.csv----2-

erdewit commented 1 year ago

That's an interesting difference that shouldn't be there. All I can think of is a difference in socket protocol version, although both ib_insync and ibapi should be using v176 when combined with a new TWS.

There is a TWS config setting for the API of "Round account values to nearest whole number" - not sure if that applies to executions as well and supposedly you're not using two different TWS instances.

snielsen-sgiam commented 1 year ago

Is there a way I can lookup/confirm which protocol version is being used?

The "Round account values to nearest whole number" setting is off and I am indeed only using one instance of TWS (Build 10.19.1k)

I can get expanded API logs if needs be, or any other debugging info that might be helpful.

erdewit commented 1 year ago

Is there a way I can lookup/confirm which protocol version is being used?

With ibapi it's client.serverVersion(), with ib_insync it's ib.client.serverVersion().

snielsen-sgiam commented 1 year ago

Huh, when querying for the server version I get:

ib_insyc: 176 ibapi: 157

I assumed that the server version meant the version of/inside TWS which I wouldn't expect to be different depending on what client was connecting to it. I only have one instance of TWS running, but just in case I triple checked IP addresses/ports etc. and I am connecting to the same TWS instance.

pip freeze reports ibapi==9.81.1.post1

snielsen-sgiam commented 1 year ago

Did some more digging, found that the version of ibapi installed through pip is not the latest one, installed 10.19.1 then the ibapi code reports server version 176 and incorrectly rounds partial share amounts.

So it looks like this is pretty definitively a bug in the IB API then?

erdewit commented 1 year ago

So it looks like this is pretty definitively a bug in the IB API then?

Yeah it's a bug in TWS. It should be the other way around, int sizes for the old protocol and float sizes for the newer versions.

snielsen-sgiam commented 1 year ago

Ok, I've filed a bug report with IB. Thanks so much for helping me track it down!