async def listen_for_trades(self, ev_loop: asyncio.BaseEventLoop, output: asyncio.Queue): while True: try: ws_path: str = "/".join([ f"{convert_to_exchange_trading_pair(trading_pair).lower()}@trade" for trading_pair in self._trading_pairs ]) url = DIFF_STREAM_URL.format(self._domain) stream_url: str = f"{url}/{ws_path}" async with websockets.connect(stream_url) as ws: ws: websockets.WebSocketClientProtocol = ws async for raw_msg in self._inner_messages(ws): msg = ujson.loads(raw_msg) trade_msg: OrderBookMessage = BinanceOrderBook.trade_message_from_exchange( msg) output.put_nowait(trade_msg) except asyncio.CancelledError: raise except Exception: self.logger().error( "Unexpected error with WebSocket connection. Retrying after 30 seconds...", exc_info=True) await asyncio.sleep(30.0)
async def listen_for_trades(self, ev_loop: asyncio.BaseEventLoop, output: asyncio.Queue): ws = None while True: try: ws = await self._create_websocket_connection() payload = { "method": "SUBSCRIBE", "params": [ f"{binance_utils.convert_to_exchange_trading_pair(trading_pair).lower()}@trade" for trading_pair in self._trading_pairs ], "id": self.TRADE_STREAM_ID } await ws.send_json(payload) async for json_msg in self._iter_messages(ws): if "result" in json_msg: continue trade_msg: OrderBookMessage = BinanceOrderBook.trade_message_from_exchange( json_msg) output.put_nowait(trade_msg) except asyncio.CancelledError: raise except Exception: self.logger().error( "Unexpected error with WebSocket connection. Retrying after 30 seconds...", exc_info=True) finally: ws and await ws.close() await self._sleep(30.0)
async def listen_for_trades(self, ev_loop: asyncio.AbstractEventLoop, output: asyncio.Queue): """ Reads the trade events queue. For each event creates a trade message instance and adds it to the output queue :param ev_loop: the event loop the method will run in :param output: a queue to add the created trade messages """ message_queue = self._message_queue[CONSTANTS.TRADE_EVENT_TYPE] while True: try: json_msg = await message_queue.get() if "result" in json_msg: continue trading_pair = await BinanceAPIOrderBookDataSource.trading_pair_associated_to_exchange_symbol( symbol=json_msg["s"], domain=self._domain, api_factory=self._api_factory, throttler=self._throttler, time_synchronizer=self._time_synchronizer) trade_msg: OrderBookMessage = BinanceOrderBook.trade_message_from_exchange( json_msg, {"trading_pair": trading_pair}) output.put_nowait(trade_msg) except asyncio.CancelledError: raise except Exception: self.logger().exception( "Unexpected error when processing public trade updates from exchange" )
async def _parse_trade_message(self, raw_message: Dict[str, Any], message_queue: asyncio.Queue): if "result" not in raw_message: trading_pair = await self._connector.trading_pair_associated_to_exchange_symbol( symbol=raw_message["s"]) trade_message = BinanceOrderBook.trade_message_from_exchange( raw_message, {"trading_pair": trading_pair}) message_queue.put_nowait(trade_message)
def test_trade_message_from_exchange(self): trade_update = { "e": "trade", "E": 1234567890123, "s": "COINALPHAHBOT", "t": 12345, "p": "0.001", "q": "100", "b": 88, "a": 50, "T": 123456785, "m": True, "M": True } trade_message = BinanceOrderBook.trade_message_from_exchange( msg=trade_update, metadata={"trading_pair": "COINALPHA-HBOT"}) self.assertEqual("COINALPHA-HBOT", trade_message.trading_pair) self.assertEqual(OrderBookMessageType.TRADE, trade_message.type) self.assertEqual(1234567890.123, trade_message.timestamp) self.assertEqual(-1, trade_message.update_id) self.assertEqual(-1, trade_message.first_update_id) self.assertEqual(12345, trade_message.trade_id)