async def listen_for_order_book_snapshots(self, ev_loop: asyncio.BaseEventLoop, output: asyncio.Queue): """ Listen for orderbook snapshots by fetching orderbook """ while True: try: trading_pairs: List[str] = await self.get_trading_pairs() for trading_pair in trading_pairs: try: snapshot: Dict[str, any] = await self.get_orderbook( trading_pair) snapshot_timestamp: float = pd.Timestamp( snapshot["timestamp"]).timestamp() snapshot_msg: OrderBookMessage = BitcoinComOrderBook.snapshot_message_from_exchange( add_event_type(EventTypes.OrderbookSnapshot, snapshot), snapshot_timestamp, metadata={"trading_pair": trading_pair}) output.put_nowait(snapshot_msg) self.logger().debug( f"Saved order book snapshot for {trading_pair}") # Be careful not to go above API rate limits. await asyncio.sleep(5.0) except asyncio.CancelledError: raise except Exception: self.logger().network( f"Unexpected error with WebSocket connection.", exc_info=True, app_warning_msg= f"Unexpected error with WebSocket connection. Retrying in 5 seconds. " f"Check network connection.") await asyncio.sleep(5.0) this_hour: pd.Timestamp = pd.Timestamp.utcnow().replace( minute=0, second=0, microsecond=0) next_hour: pd.Timestamp = this_hour + pd.Timedelta(hours=1) delta: float = next_hour.timestamp() - time.time() await asyncio.sleep(delta) except asyncio.CancelledError: raise except Exception: self.logger().error("Unexpected error.", exc_info=True) await asyncio.sleep(5.0)
async def listen_for_trades(self, ev_loop: asyncio.BaseEventLoop, output: asyncio.Queue): """ Listen for trades using websocket "updateTrades" method """ while True: try: ws = BitcoinComWebsocket() await ws.connect() trading_pairs: List[str] = await self.get_trading_pairs() for trading_pair in trading_pairs: await ws.subscribe( "subscribeTrades", { "symbol": trading_pair, "limit": 1 # we only care about updates, this sets the initial snapshot limit }) async for response in ws.on("updateTrades"): if (response["error"] is not None): self.logger().error(response["error"]) continue trades = response["data"]["data"] for trade in trades: trade_timestamp: float = pd.Timestamp( trade["timestamp"]).timestamp() trade_msg: OrderBookMessage = BitcoinComOrderBook.trade_message_from_exchange( add_event_type(EventTypes.TradesUpdate, trade), trade_timestamp, metadata={"trading_pair": trading_pair}) output.put_nowait(trade_msg) except asyncio.CancelledError: raise except Exception: self.logger().error("Unexpected error.", exc_info=True) await asyncio.sleep(5.0) finally: await ws.disconnect()
async def get_tracking_pairs( self) -> Dict[str, BitcoinComOrderBookTrackerEntry]: trading_pairs: List[str] = await self.get_trading_pairs() tracking_pairs: Dict[str, BitcoinComOrderBookTrackerEntry] = {} number_of_pairs: int = len(trading_pairs) for index, trading_pair in enumerate(trading_pairs): try: snapshot: Dict[str, any] = await self.get_orderbook(trading_pair) snapshot_timestamp: float = pd.Timestamp( snapshot["timestamp"]).timestamp() snapshot_msg: OrderBookMessage = BitcoinComOrderBook.snapshot_message_from_exchange( add_event_type(EventTypes.OrderbookSnapshot, snapshot), snapshot_timestamp, metadata={"trading_pair": trading_pair}) order_book: OrderBook = self.order_book_create_function() active_order_tracker: BitcoinComActiveOrderTracker = BitcoinComActiveOrderTracker( ) bids, asks = active_order_tracker.convert_snapshot_message_to_order_book_row( snapshot_msg) order_book.apply_snapshot(bids, asks, snapshot_msg.update_id) tracking_pairs[trading_pair] = BitcoinComOrderBookTrackerEntry( trading_pair, snapshot_timestamp, order_book, active_order_tracker) self.logger().info( f"Initialized order book for {trading_pair}. " f"{index+1}/{number_of_pairs} completed.") await asyncio.sleep(0.6) except IOError: self.logger().network( f"Error getting snapshot for {trading_pair}.", exc_info=True, app_warning_msg= f"Error getting snapshot for {trading_pair}. Check network connection." ) except Exception: self.logger().error( f"Error initializing order book for {trading_pair}. ", exc_info=True) return tracking_pairs
async def listen_for_order_book_diffs(self, ev_loop: asyncio.BaseEventLoop, output: asyncio.Queue): """ Listen for orderbook diffs using websocket "updateOrderbook" method """ while True: try: ws = BitcoinComWebsocket() await ws.connect() trading_pairs: List[str] = await self.get_trading_pairs() for trading_pair in trading_pairs: await ws.subscribe("subscribeOrderbook", {"symbol": trading_pair}) async for response in ws.on("updateOrderbook"): if (response["error"] is not None): self.logger().error(response["error"]) continue diff = response["data"] diff_timestamp: float = pd.Timestamp( diff["timestamp"]).timestamp() orderbook_msg: OrderBookMessage = BitcoinComOrderBook.diff_message_from_exchange( add_event_type(EventTypes.OrderbookUpdate, diff), diff_timestamp, metadata={"trading_pair": trading_pair}) output.put_nowait(orderbook_msg) except asyncio.CancelledError: raise except Exception: self.logger().network( f"Unexpected error with WebSocket connection.", exc_info=True, app_warning_msg= f"Unexpected error with WebSocket connection. Retrying in 30 seconds. " f"Check network connection.") await asyncio.sleep(30.0) finally: await ws.disconnect()