coinbase / coinbase-pro-node

DEPRECATED — The official Node.js library for Coinbase Pro
Apache License 2.0
844 stars 316 forks source link

Trade timestamps out of order / perhaps incorrectly formatted #358

Closed matthewdowney closed 5 years ago

matthewdowney commented 5 years ago

Hi there, I'm not entirely sure that this is the correct place to put an issue with the API itself, so let me know if there's a more appropriate place for me to open this issue.

When querying historical trades via the public rest endpoint (the /products/product-id/trades path), I'm seeing pages where the order ids are in order, but the timestamps are not. For example, querying the recent BTC-USD trades just now at /products/BTC-USD/trades, I see this subset with trade ids:

[{"time":"2019-05-12T17:58:07.313Z",
  "trade_id":63556883,
  "price":"6914.09000000",
  "size":"0.02917501",
  "side":"buy"},
 {"time":"2019-05-12T17:58:05.77Z",  # This would appear to happen at 77ms after 17:58:05
  "trade_id":63556882,
  "price":"6914.08000000",
  "size":"0.01038704",
  "side":"buy"},
 {"time":"2019-05-12T17:58:05.693Z", # ... and this at 693ms after 17:58:05
  "trade_id":63556881,
  "price":"6917.85000000",
  "size":"0.00130042",
  "side":"sell"}]

Is "2019-05-12T17:58:05.77Z" == "2019-05-12T17:58:05.077Z"?

Now, the pages are supposed to be in reverse chronological order, and my querying code is throwing a warning at me because it thinks that 2019-05-12T17:58:05.77Z does not come after the previous trade's timestamp 2019-05-12T17:58:05.693Z, and that's an issue.

With regard to timestamps, the API docs say

Unless otherwise specified, all timestamps from API are returned in ISO 8601 with microseconds. Make sure you can parse the following ISO 8601 format. Most modern languages and libraries will handle this without issues.

I was pretty sure the standard requires that .77Z be the same as .077Z, but since interpreting it as .770Z would fix the ordering of that subset of trades, I figured that I was just wrong about that.

Is "2019-05-12T17:46:45.49Z" == "2019-05-12T17:46:45.490Z"

But then, I saw another subset of trades, and this subset was out of order according to my new way of looking at timestamps!

[{"time":"2019-05-12T17:46:47.473Z",
  "trade_id":63556261,
  "price":"6903.18000000",
  "size":"0.00195544",
  "side":"sell"},
 {"time":"2019-05-12T17:46:45.423Z", # This was at 423ms past 17:46:45
  "trade_id":63556260,
  "price":"6903.18000000",
  "size":"0.02334265",
  "side":"sell"},
 {"time":"2019-05-12T17:46:45.49Z", # This was at ... 490ms, 49ms?... past 17:46:45
  "trade_id":63556259,
  "price":"6903.18000000",
  "size":"0.09523989",
  "side":"sell"}]

If interpreting .77Z as .770Z would have fixed the ordering in the first example, doing the same and interpreting .49Z as .490Z (instead of .049Z, as I was doing originally) would make this subset of trades out of order.

What's the proper format?

So I'm stumped. I'm pretty sure the way I was doing it originally conforms to the ISO standard, which means that the first set of the trades is out of order, but even if I'm wrong about how to interpret the millisecond part of the timestamp and pick the other way of parsing the timestamps there are still trades out of order. Is there a third option?

I'm definitely willing to admit the possibility that I'm parsing these timestamps wrong, but if that's the case what's the rule for parsing? I don't think the trades are actually happening out of order since all of the trade ids are in order, plus it would be a huge violation of price-time priority, but maybe they're being timestamped incorrectly somehow?

Any help would be much appreciated!

matthewdowney commented 5 years ago

For the time being I've written something that parses the timestamps in a way that assumes that the trade ids are in order. If anyone has a better suggestion I'm all ears though! :)

livingsilver94 commented 5 years ago

Can we have an official reply on this? I'm facing the same problem and I don't know how to deal with it.

fb55 commented 5 years ago

We use fractional seconds, so mentally appending zeros to the end is the right model.

These timestamps should be primarily used for displaying information to users, and logical time (sequence numbers and trade ids) should be used for all other purposes. Not sure what happened here, but it is not out of the question that different systems supplied timestamps here or that a system's clock was resynchronized in between timestamps.