danpaquin / coinbasepro-python

The unofficial Python client for the Coinbase Pro API
MIT License
1.82k stars 733 forks source link

Websocket provides Incorrect prices #360

Closed gegenki closed 3 years ago

gegenki commented 5 years ago

Simple code looks like this.

db = mongo_client.crypto
collection = db.btceur

wsClient = cbpro.WebsocketClient(url="wss://ws-feed.pro.coinbase.com", products="BTC-EUR",
    mongo_collection=collection, should_print=True)

wsClient.start()

s = sched.scheduler(time.time, time.sleep)
def cleanUp(sc):
  nBefore = collection.count_documents({})
  collection.delete_many( {"reason":{ "$ne": "filled"}} )
  nAfter = collection.count_documents({})
  print("Cleanup", "| Before:", nBefore, "| After:", nAfter)
  s.enter(30, 1, cleanUp, (sc,))

s.enter(30, 1, cleanUp, (s,))
s.run()

Every 30 seconds it removes anything I don't care about from the database. Ran it last night and tried to calculate the close price at each minute this morning. Found some strange values. Checked the log

{'type': 'received', 'order_id': '23c64a7c-20c2-4ca0-bcd9-18b3b495ad0a', 'order_type': 'limit', 'size': '0.00154797', 'price': '5168.05000000', 'side': 'buy', 'client_oid': '07eb72c0-89aa-409e-b1ef-b4106fd1a740', 'product_id': 'BTC-EUR', 'sequence': 5216764506, 'time': '2019-04-14T01:45:49.441000Z'} {'type': 'done', 'side': 'buy', 'order_id': '23c64a7c-20c2-4ca0-bcd9-18b3b495ad0a', 'reason': 'filled', 'product_id': 'BTC-EUR', 'price': '5168.05000000', 'remaining_size': '0.00000000', 'sequence': 5216764508, 'time': '2019-04-14T01:45:49.441000Z'}

This shows a BTC-EUR order filled last night at 1:45 UTC for at a price of 5168.05. The price hasn't been that high since November. If I check on GDAX, the price at that time was 4505

Screen Shot 2019-04-14 at 10 11 33

(Note - time difference is because my computer is in UTC+1)

I have many examples of these supposedly filled trades at wildly inaccurate prices.

uclatommy commented 5 years ago

I'm curious to know how you decided this is an error. People could be self-trading or trading bots could be doing all sorts of weird stuff, especially when trade volume is extremely thin. I can imagine that someone could pump prices this way by making small self-trades at higher prices that fill when no one else is trading hoping to hit some trading bot price thresholds in order for them to pile in when they detect the transaction.

gegenki commented 5 years ago

Looking for 'match' rather than 'filled' does solve the issue for me.

Rather than deleting all the additional data I just wrote it to the database. Over the same period, many of the fills are at totally different prices to the matches. I am also interested in what uclatommy means because - I have no idea what that data is supposed to represent.

uclatommy commented 5 years ago

@noah222, I think this is only possible when trading volume is very thin, like what gegenki shows in the graph. You can see that at some periods, there are no trades suggesting that there is a wide buy-sell spread. When no one is trading, I imagine you could create a limit sell at the high end, then a limit buy with the exact same price, and the two orders will match each other. Coinbase defines market orders as maker orders and limit orders as taker orders in their pricing structure, but I'm guessing that distinction is just for pricing. There should be no reason why a limit order cannot match another limit order.

mcardillo55 commented 3 years ago

Resolved. Closing.