Closed JamesKBowler closed 5 years ago
Get Product Ticker
Snapshot information about the last trade (tick), best bid/ask and 24h volume.
{ "trade_id": 4729088, "price": "333.99", "size": "0.193", "bid": "333.98", "ask": "333.99", "volume": "5957.11914015", "time": "2015-11-14T20:46:03.511254Z" }
Thanks but I was referring to the websocket stream.
Volume is stored in the historical data. So you can get it in the historical data API or you can store/log each transaction in the websocket and sum them to come up with volume for your specifiied interval. The best idea is to log the stream data then you can sum it and dice it into any size sections later on.
@noah222 Thanks, I guessed as much, only i'm not sure what approach to take because each message type is different.
Do you have any code implementation to share?
Cheers
I have many solutions, but they are very specific to my other code and is not yet modular. Let me know exactly where you are in your process and I can try to point you in the right direction with examples.
The message type does not really matter, what matters is what you do with it. What i mean is any message is just some text that can be sorted, manipulated, appended to lists, and stored in some form. So it mostly depends on what format you want the data to be in, and what granularity you need for the next steps of your code.
@noah222 Thanks, I guessed as much, only i'm not sure what approach to take because each message type is different.
Do you have any code implementation to share?
Cheers
Understand what you are saying, I guess the correct question should be "how do I calculate executed trade volume" ... or something along those lines : )
Ok, think I may have cracked the process as the volume is now matching up with the [https://pro.coinbase.com]() web platform trade history.
def on_message(self, message):
self._volume = Decimal('0.0')
...snip
def match(self, order):
size = Decimal(order['size'])
price = Decimal(order['price'])
if order['side'] == 'buy':
bids = self.get_bids(price)
if not bids:
return
assert bids[0]['id'] == order['maker_order_id']
self._volume += size
if bids[0]['size'] == size:
self.set_bids(price, bids[1:])
else:
bids[0]['size'] -= size
self.set_bids(price, bids)
else:
asks = self.get_asks(price)
if not asks:
return
assert asks[0]['id'] == order['maker_order_id']
self._volume += size
if asks[0]['size'] == size:
self.set_asks(price, asks[1:])
else:
asks[0]['size'] -= size
self.set_asks(price, asks)
1) The "full" channel has the L3 order book AND the matches. You can use the matches there to add up the volumes.
2) But the "full" channel is space intensive, so unless you're doing some very deep simulations on fills, you're probably better off using the "level2" channel. Plus you don't have to worry as much about missing websocket data mangling your orderbook state. You should combine the "level2" channel with the "matches" channel (which is basically every single trade-hits-order-book).
3) Avoid the ticker channel, it is busted. It should trigger a tick every time the inside quotes change, but I've found it to be unreliable. Also, the volumes seem to be the volume of the last match only, so it'll undercount actual volume.
4) See a small sample of the type "match" from the match channel. Summing up the sizes should give you volumes matching CB (I've tested this).
BTC-USD|match|1563300116.150038|{"time": "2019-07-16T18:01:56.144000Z", "type": "match", "product_id": "BTC-USD", "taker_order_id": "0ac73eac-689e-4c9b-bc90-59e4f1d674c5", "side": "buy", "maker_order_id": "d618bea9-7f69-4454-965c-41736064d573", "sequence": 10214237094, "size": "0.01822233", "trade_id": 70027984, "price": "9760.55000000"} ETH-USD|match|1563300116.167355|{"time": "2019-07-16T18:01:56.161000Z", "type": "match", "product_id": "ETH-USD", "taker_order_id": "a9e569d0-0d60-46b3-9256-de098ef63e6c", "side": "sell", "maker_order_id": "2e921b54-5175-4bca-a5fb-94b330d1a0d4", "sequence": 7010941800, "size": "2.00000000", "trade_id": 50159413, "price": "202.46000000"} ETH-USD|match|1563300116.168052|{"time": "2019-07-16T18:01:56.161000Z", "type": "match", "product_id": "ETH-USD", "taker_order_id": "a9e569d0-0d60-46b3-9256-de098ef63e6c", "side": "sell", "maker_order_id": "c5fa10f4-79d3-470d-ad74-25de7a04b506", "sequence": 7010941802, "size": "3.07700000", "trade_id": 50159414, "price": "202.47000000"} ETH-USD|match|1563300116.168420|{"time": "2019-07-16T18:01:56.161000Z", "type": "match", "product_id": "ETH-USD", "taker_order_id": "a9e569d0-0d60-46b3-9256-de098ef63e6c", "side": "sell", "maker_order_id": "c9aa97b3-8aac-4bd7-9d0c-5b419da8ff1c", "sequence": 7010941804, "size": "5.00000000", "trade_id": 50159415, "price": "202.48000000"} ETH-USD|match|1563300116.168890|{"time": "2019-07-16T18:01:56.161000Z", "type": "match", "product_id": "ETH-USD", "taker_order_id": "a9e569d0-0d60-46b3-9256-de098ef63e6c", "side": "sell", "maker_order_id": "d30a79fe-c170-47d1-9b0d-0837bd485d8c", "sequence": 7010941806, "size": "10.33800000", "trade_id": 50159416, "price": "202.49000000"} ETH-USD|match|1563300116.268488|{"time": "2019-07-16T18:01:56.251000Z", "type": "match", "product_id": "ETH-USD", "taker_order_id": "4275aefc-7878-425d-abb2-6115b81842aa", "side": "sell", "maker_order_id": "067ec5d6-be99-4a1e-ad04-24b31e4e10c7", "sequence": 7010941848, "size": "2.00000000", "trade_id": 50159417, "price": "202.55000000"} ETH-USD|match|1563300116.269007|{"time": "2019-07-16T18:01:56.251000Z", "type": "match", "product_id": "ETH-USD", "taker_order_id": "4275aefc-7878-425d-abb2-6115b81842aa", "side": "sell", "maker_order_id": "6305d147-c4ca-480a-bc48-7a8b962d6f95", "sequence": 7010941850, "size": "2.00000000", "trade_id": 50159418, "price": "202.56000000"} ETH-USD|match|1563300116.269297|{"time": "2019-07-16T18:01:56.251000Z", "type": "match", "product_id": "ETH-USD", "taker_order_id": "4275aefc-7878-425d-abb2-6115b81842aa", "side": "sell", "maker_order_id": "71e89b1c-ad44-4765-87c4-b0c32c15f33d", "sequence": 7010941852, "size": "10.00000000", "trade_id": 50159419, "price": "202.56000000"} ETH-USD|match|1563300116.293319|{"time": "2019-07-16T18:01:56.289000Z", "type": "match", "product_id": "ETH-USD", "taker_order_id": "d89c5740-86c0-484a-b82c-6ec6dcb7f862", "side": "sell", "maker_order_id": "b3891f47-6de4-460f-832b-3625b356183c", "sequence": 7010941872, "size": "12.93500000", "trade_id": 50159420, "price": "202.57000000"} LTC-USD|match|1563300116.449671|{"time": "2019-07-16T18:01:56.439000Z", "type": "match", "product_id": "LTC-USD", "taker_order_id": "79c4cdc4-4185-4aca-8d77-274d1557707d", "side": "buy", "maker_order_id": "db542f29-5ae7-45bb-aef1-2d03a5cbe9ed", "sequence": 3687224576, "size": "14.65000000", "trade_id": 40592623, "price": "80.36000000"} BTC-USD|match|1563300116.450155|{"time": "2019-07-16T18:01:56.438000Z", "type": "match", "product_id": "BTC-USD", "taker_order_id": "9d329d15-f1bf-450a-adce-f7d7fbbcad7d", "side": "sell", "maker_order_id": "a5c15fc1-f0ae-4021-9fe4-3954781e2955", "sequence": 10214237148, "size": "0.47973902", "trade_id": 70027985, "price": "9760.56000000"} BTC-USD|match|1563300116.450754|{"time": "2019-07-16T18:01:56.438000Z", "type": "match", "product_id": "BTC-USD", "taker_order_id": "9d329d15-f1bf-450a-adce-f7d7fbbcad7d", "side": "sell", "maker_order_id": "afca4f3b-5e66-4105-a515-bfd30ac42acb", "sequence": 10214237150, "size": "0.39490602", "trade_id": 70027986, "price": "9760.56000000"}
On Tue, Jul 16, 2019 at 2:18 PM James Bowler notifications@github.com wrote:
ok, think I may have something here because they match up with the coinbasepro trade history.
def on_message(self, message): self._volume = Decimal('0.0') ...snip def match(self, order): size = Decimal(order['size']) price = Decimal(order['price']) if order['side'] == 'buy': bids = self.get_bids(price) if not bids: return assert bids[0]['id'] == order['maker_order_id'] self._volume += size if bids[0]['size'] == size: self.set_bids(price, bids[1:]) else: bids[0]['size'] -= size self.set_bids(price, bids) else: asks = self.get_asks(price) if not asks: return assert asks[0]['id'] == order['maker_order_id'] self._volume += size if asks[0]['size'] == size: self.set_asks(price, asks[1:]) else: asks[0]['size'] -= size self.set_asks(price, asks)
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/danpaquin/coinbasepro-python/issues/367?email_source=notifications&email_token=AABBL6GWNEF6FKQXOHEFUBTP7YGIXA5CNFSM4H2ZNUF2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD2BWWQI#issuecomment-511929153, or mute the thread https://github.com/notifications/unsubscribe-auth/AABBL6HH2LPSCN2SVAQR5D3P7YGIXANCNFSM4H2ZNUFQ .
awesome, that is great info! I will close this one off. Thanks to all.
Hi, How would I go about calculating volume for each tick. I am not sure which message type I need to parse.
Thanks
James