def __init__(self, product_id='BTC-USD', log_to=None): super(OrderBook, self).__init__(products=product_id) self._asks = SortedDict() self._bids = SortedDict() self._client = PublicClient() self._sequence = -1 self._log_to = log_to if self._log_to: assert hasattr(self._log_to, 'write') self._current_ticker = None
def __init__(self, product_id, log_to=None): self._asks = RBTree() self._bids = RBTree() self._client = PublicClient() self._sequence = -1 self.sync = -1 self.product_id = product_id self._log_to = log_to if self._log_to: assert hasattr(self._log_to, 'write') self._current_ticker = None
def _listen_trader(self): from public_client import PublicClient snapshot = PublicClient().get_product_order_book( product_id=self.products[0], level=3) self.order_book.reset_book(snapshot) self._init_hb() # Avoid string comparison self.running_code = None while self.running_code is None: try: now = datetime.datetime.now() self._check_hb(now) for i in range(10): data = self.ws.recv() mkt_msg = json.loads(data) self.order_book.on_message(mkt_msg) if mkt_msg['type'] == 'match': self.trader.on_mkt_trade(now, mkt_msg) self.trader.on_mkt_msg_end(now) self._check_user_msg() except WebSocketConnectionClosedException as e: self._on_error(e, data) except ValueError as e: self._on_error(e, data) except Exception as e: self._on_error(e, data)
def _listen_recorder(self): ss_now = datetime.datetime.now() from public_client import PublicClient snapshot = PublicClient().get_product_order_book( product_id=self.products[0], level=3) self._record_msg(ss_now, "snapshot", snapshot) self._init_hb() # Avoid string comparison self.running_code = None while self.running_code is None: try: now = datetime.datetime.now() self._check_hb(now) for i in range(10): # TODO: this is a sync call, make it async data = self.ws.recv() mkt_msg = json.loads(data) self._record_msg(now, "update", mkt_msg) self._check_user_msg() except WebSocketConnectionClosedException as e: self._on_error(e, data) except ValueError as e: self._on_error(e, data) except Exception as e: self._on_error(e, data)
class OrderBook(WebsocketClient): def __init__(self, product_id='BTC-USD', log_to=None): super(OrderBook, self).__init__(products=product_id) self._asks = SortedDict() self._bids = SortedDict() self._client = PublicClient() self._sequence = -1 self._log_to = log_to if self._log_to: assert hasattr(self._log_to, 'write') self._current_ticker = None @property def product_id(self): ''' Currently OrderBook only supports a single product even though it is stored as a list of products. ''' return self.products[0] def on_open(self): self._sequence = -1 print("-- Subscribed to OrderBook! --\n") def on_close(self): print("\n-- OrderBook Socket Closed! --") def reset_book(self): self._asks = SortedDict() self._bids = SortedDict() res = self._client.get_product_order_book(product_id=self.product_id, level=3) for bid in res['bids']: self.add({ 'id': bid[2], 'side': 'buy', 'price': Decimal(bid[0]), 'size': Decimal(bid[1]) }) for ask in res['asks']: self.add({ 'id': ask[2], 'side': 'sell', 'price': Decimal(ask[0]), 'size': Decimal(ask[1]) }) self._sequence = res['sequence'] def on_message(self, message): if self._log_to: pickle.dump(message, self._log_to) sequence = message.get('sequence', -1) if self._sequence == -1: self.reset_book() return if sequence <= self._sequence: # ignore older messages (e.g. before order book initialization from getProductOrderBook) return elif sequence > self._sequence + 1: self.on_sequence_gap(self._sequence, sequence) return msg_type = message['type'] if msg_type == 'open': self.add(message) elif msg_type == 'done' and 'price' in message: self.remove(message) elif msg_type == 'match': self.match(message) self._current_ticker = message elif msg_type == 'change': self.change(message) self._sequence = sequence def on_sequence_gap(self, gap_start, gap_end): self.reset_book() print( 'Error: messages missing ({} - {}). Re-initializing book at sequence.' .format(gap_start, gap_end, self._sequence)) def add(self, order): order = { 'id': order.get('order_id') or order['id'], 'side': order['side'], 'price': Decimal(order['price']), 'size': Decimal(order.get('size') or order['remaining_size']) } if order['side'] == 'buy': bids = self.get_bids(order['price']) if bids is None: bids = [order] else: bids.append(order) self.set_bids(order['price'], bids) else: asks = self.get_asks(order['price']) if asks is None: asks = [order] else: asks.append(order) self.set_asks(order['price'], asks) def remove(self, order): price = Decimal(order['price']) if order['side'] == 'buy': bids = self.get_bids(price) if bids is not None: bids = [o for o in bids if o['id'] != order['order_id']] if len(bids) > 0: self.set_bids(price, bids) else: self.remove_bids(price) else: asks = self.get_asks(price) if asks is not None: asks = [o for o in asks if o['id'] != order['order_id']] if len(asks) > 0: self.set_asks(price, asks) else: self.remove_asks(price) 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'] 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'] if asks[0]['size'] == size: self.set_asks(price, asks[1:]) else: asks[0]['size'] -= size self.set_asks(price, asks) def change(self, order): try: new_size = Decimal(order['new_size']) except KeyError: return try: price = Decimal(order['price']) except KeyError: return if order['side'] == 'buy': bids = self.get_bids(price) if bids is None or not any(o['id'] == order['order_id'] for o in bids): return index = [b['id'] for b in bids].index(order['order_id']) bids[index]['size'] = new_size self.set_bids(price, bids) else: asks = self.get_asks(price) if asks is None or not any(o['id'] == order['order_id'] for o in asks): return index = [a['id'] for a in asks].index(order['order_id']) asks[index]['size'] = new_size self.set_asks(price, asks) tree = self._asks if order['side'] == 'sell' else self._bids node = tree.get(price) if node is None or not any(o['id'] == order['order_id'] for o in node): return def get_current_ticker(self): return self._current_ticker def get_current_book(self): result = { 'sequence': self._sequence, 'asks': [], 'bids': [], } for ask in self._asks: try: # There can be a race condition here, where a price point is removed # between these two ops this_ask = self._asks[ask] except KeyError: continue for order in this_ask: result['asks'].append( [order['price'], order['size'], order['id']]) for bid in self._bids: try: # There can be a race condition here, where a price point is removed # between these two ops this_bid = self._bids[bid] except KeyError: continue for order in this_bid: result['bids'].append( [order['price'], order['size'], order['id']]) return result def get_ask(self): return self._asks.peekitem(0)[0] def get_asks(self, price): return self._asks.get(price) def remove_asks(self, price): del self._asks[price] def set_asks(self, price, asks): self._asks[price] = asks def get_bid(self): return self._bids.peekitem(-1)[0] def get_bids(self, price): return self._bids.get(price) def remove_bids(self, price): del self._bids[price] def set_bids(self, price, bids): self._bids[price] = bids
# 'size': 1.0, # 'price': 1.0, # 'side': 'buy', # 'product_id': 'BTC-USD', # } # r = requests.post(api_url + 'orders', json=order, auth=auth) # print r.json() # {"id": "0428b97b-bec1-429e-a94c-59992926778d"} ### Option 2: use python sdk, I copy the sdk code from https://github.com/danpaquin/coinbasepro-python and made some modification # the main reason to do this is package conficts makes me couldn't install cbpro package fully. auth_client = AuthenticatedClient(API_KEY, API_SECRET, API_PASS) js = auth_client.get_accounts() # print(js) ### Option 3, use public client to get crypto information public_client = PublicClient() eth_history_js = public_client.get_product_historic_rates( product_id='ETH-USD', start='2020-11-14T20:46:03.511254Z', end='2020-11-14T21:46:03.511254Z', granularity=60) print(eth_history_js) eth_trades_fetch = public_client.get_product_trades(product_id='ETH-USD') res = eth_trades_fetch.send() print(res)
from public_client import PublicClient import datetime as DT import time batch_size = 300 candle = 3600 n_batch = 50 start_time = 1552717954 reader = PublicClient() f = open('data.py', 'w+') for i in range(n_batch): batch_end = DT.datetime.utcfromtimestamp(start_time - (i * candle * batch_size)).isoformat() batch_start = DT.datetime.utcfromtimestamp(start_time - ( (i + 1) * candle * batch_size)).isoformat() data = reader.get_product_historic_rates('btc-usd', start=str(batch_start), end=str(batch_end), granularity=candle) time.sleep(1) for step in range(len(data)): f.write('%f ,' % (data[step][1])) f.close()