sparkstartconsulting / IBKR-API-Rust

Port of Interactive Broker's trading API written in Rust
MIT License
126 stars 39 forks source link

Timestamps for ticks? #29

Open virtualritz opened 2 years ago

virtualritz commented 2 years ago

I am trying to get a similar data structure like the Ticker class in the Python ib_sync lib filled.

I am looking for something like the output from this Python code snippet:

0 async tick Stock: 788.68 Ticker(contract=Stock(symbol='TSLA', exchange='SMART', currency='USD'), time=datetime.datetime(2021, 9, 29, 15, 3, 8, 301215, tzinfo=datetime.timezone.utc), bid=788.6, bidSize=1, ask=788.83, askSize=3, last=788.68, lastSize=1, volume=68131, open=779.8, high=793.5, low=779.1, close=777.56, halted=0.0, ticks=[TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 301215, tzinfo=datetime.timezone.utc), tickType=1, price=788.6, size=1), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 301215, tzinfo=datetime.timezone.utc), tickType=2, price=788.83, size=3), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 301215, tzinfo=datetime.timezone.utc), tickType=4, price=788.68, size=1), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 301215, tzinfo=datetime.timezone.utc), tickType=5, price=788.68, size=1), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 301215, tzinfo=datetime.timezone.utc), tickType=8, price=-1.0, size=68131), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 301215, tzinfo=datetime.timezone.utc), tickType=6, price=793.5, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 301215, tzinfo=datetime.timezone.utc), tickType=7, price=779.1, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 301215, tzinfo=datetime.timezone.utc), tickType=9, price=777.56, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 301215, tzinfo=datetime.timezone.utc), tickType=14, price=779.8, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 301215, tzinfo=datetime.timezone.utc), tickType=49, price=0.0, size=0)])
0 async tick Stock: 329.33 Ticker(contract=Stock(symbol='UPST', exchange='SMART', currency='USD'), time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), bid=329.08, bidSize=1, ask=329.5, askSize=1, last=329.33, lastSize=1, volume=22554, open=319.01, high=332.1, low=317.33, close=313.4, halted=0.0, ticks=[TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=1, price=329.08, size=1), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=2, price=329.5, size=1), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=4, price=329.33, size=1), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=5, price=329.33, size=1), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=8, price=-1.0, size=22554), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=6, price=332.1, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=7, price=317.33, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=9, price=313.4, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=14, price=319.01, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=49, price=0.0, size=0)])
1 async tick Stock: 3338.06 Ticker(contract=Stock(symbol='AMZN', exchange='SMART', currency='USD'), time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), bid=3337.96, bidSize=1, ask=3339.96, askSize=4, last=3338.06, lastSize=1, volume=8897, open=3322.11, high=3351.3, low=3317.86, close=3315.96, halted=0.0, ticks=[TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=1, price=3337.96, size=1), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=2, price=3339.96, size=4), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=4, price=3338.06, size=1), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=5, price=3338.06, size=1), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=8, price=-1.0, size=8897), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=6, price=3351.3, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=7, price=3317.86, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=9, price=3315.96, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=14, price=3322.11, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=49, price=0.0, size=0)])
2 async tick Stock: 2729.48 Ticker(contract=Stock(symbol='GOOGL', exchange='SMART', currency='USD'), time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), bid=2728.45, bidSize=1, ask=2729.85, askSize=2, last=2729.48, lastSize=1, volume=4194, open=2739.6, high=2743.02, low=2713.05, close=2716.6, halted=0.0, ticks=[TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=1, price=2728.45, size=1), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=2, price=2729.85, size=2), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=4, price=2729.48, size=1), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=5, price=2729.48, size=1), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=8, price=-1.0, size=4194), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=6, price=2743.02, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=7, price=2713.05, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=9, price=2716.6, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=14, price=2739.6, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=49, price=0.0, size=0)])
3 async tick Stock: 208.54 Ticker(contract=Stock(symbol='NVDA', exchange='SMART', currency='USD'), time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), bid=208.54, bidSize=3, ask=208.59, askSize=2, last=208.54, lastSize=1, volume=76560, open=209.33, high=210.17, low=207.1, close=206.99, halted=0.0, ticks=[TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=1, price=208.54, size=3), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=2, price=208.59, size=2), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=4, price=208.54, size=1), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=5, price=208.54, size=1), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=8, price=-1.0, size=76560), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=6, price=210.17, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=7, price=207.1, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=9, price=206.99, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=14, price=209.33, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 323455, tzinfo=datetime.timezone.utc), tickType=49, price=0.0, size=0)])
0 async tick Stock: 282.18 Ticker(contract=Stock(symbol='BNTX', exchange='SMART', currency='USD'), time=datetime.datetime(2021, 9, 29, 15, 3, 8, 329196, tzinfo=datetime.timezone.utc), bid=282.03, bidSize=4, ask=282.34, askSize=2, last=282.18, lastSize=1, volume=13112, open=287.0, high=292.81, low=281.2, close=276.52, halted=0.0, ticks=[TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 329196, tzinfo=datetime.timezone.utc), tickType=1, price=282.03, size=4), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 329196, tzinfo=datetime.timezone.utc), tickType=2, price=282.34, size=2), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 329196, tzinfo=datetime.timezone.utc), tickType=4, price=282.18, size=1), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 329196, tzinfo=datetime.timezone.utc), tickType=5, price=282.18, size=1), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 329196, tzinfo=datetime.timezone.utc), tickType=8, price=-1.0, size=13112), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 329196, tzinfo=datetime.timezone.utc), tickType=6, price=292.81, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 329196, tzinfo=datetime.timezone.utc), tickType=7, price=281.2, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 329196, tzinfo=datetime.timezone.utc), tickType=9, price=276.52, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 329196, tzinfo=datetime.timezone.utc), tickType=14, price=287.0, size=0), TickData(time=datetime.datetime(2021, 9, 29, 15, 3, 8, 329196, tzinfo=datetime.timezone.utc), tickType=49, price=0.0, size=0)])

Now while I can fill these fields bit by bit in my Rust Tickers struct, as it happens in Python, the issue I have is the time stamps.

I only get a tick_type lastTimestamp via my wrapper's tick_string() every now and then while other data like bidPrice updates at much higher frequency. Do I just use the current UTC time to create them myself? They would obviously be off my some delta, depending on a lot of factors.

The Python code sample doesn't even list any explicit subscriptions when calling reqMktData(). What am I missing here?

virtualritz commented 2 years ago

It seems the time stamp is indeed done on the client side in Python.

So reformulating my question: is there a similar callback in the Wrapper trait that I can use to time stamp/advance my Ticker struct?

virtualritz commented 2 years ago

Looks like this would have to be done inside the Reader::run() loop? I.e. passing the wrapper all down there and the call resp. new methods added to the Wrapper trait? Or is there an existing way?