async def listen_for_trades(self, ev_loop: Optional[asyncio.BaseEventLoop],
                                output: asyncio.Queue):
        """Subscribes to the trade channel of the exchange. Adds incoming messages(of filled orders) to the output queue, to be processed by"""

        while True:
            try:
                trading_pairs: List[str] = self._trading_pairs
                async with websockets.connect(OKEX_WS_URI_PUBLIC) as ws:
                    ws: websockets.WebSocketClientProtocol = ws

                    for trading_pair in trading_pairs:
                        subscribe_request: Dict[str, Any] = {
                            "op":
                            "subscribe",
                            "args": [{
                                "channel": "trades",
                                "instType": "SPOT",
                                "instId": trading_pair,
                            }]
                        }
                        await ws.send(json.dumps(subscribe_request))

                    async for raw_msg in self._inner_messages(ws):
                        decoded_msg: str = raw_msg

                        self.logger().debug("decode menssage:" + decoded_msg)

                        if '"event":"subscribe"' in decoded_msg:
                            self.logger().debug(
                                f"Subscribed to channel, full message: {decoded_msg}"
                            )
                        elif '"channel": "orders"' in decoded_msg:
                            self.logger().debug(
                                f"Received new trade: {decoded_msg}")

                            for data in json.loads(decoded_msg)['data']:
                                trading_pair = data['instId']
                                trade_message: OrderBookMessage = OkexOrderBook.trade_message_from_exchange(
                                    data,
                                    data['uTime'],
                                    metadata={"trading_pair": trading_pair})
                                self.logger().debug(
                                    f"Putting msg in queue: {str(trade_message)}"
                                )
                                output.put_nowait(trade_message)
                        else:
                            self.logger().debug(
                                f"Unrecognized message received from OKEx websocket: {decoded_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 get_new_order_book(self, trading_pair: str) -> OrderBook:
        async with aiohttp.ClientSession() as client:
            snapshot: Dict[str, Any] = await self.get_snapshot(
                client, trading_pair)

            snapshot_msg: OrderBookMessage = OkexOrderBook.snapshot_message_from_exchange(
                snapshot,
                trading_pair,
                timestamp=snapshot['ts'],
                metadata={"trading_pair": trading_pair})
            order_book: OrderBook = self.order_book_create_function()
            order_book.apply_snapshot(snapshot_msg.bids, snapshot_msg.asks,
                                      snapshot_msg.update_id)
            return order_book
    async def listen_for_order_book_diffs(
            self, ev_loop: Optional[asyncio.BaseEventLoop],
            output: asyncio.Queue):
        """Fetches or Subscribes to the order book snapshots for each trading pair. Additionally, parses the incoming message into a OrderBookMessage and appends it into the output Queue."""
        while True:
            try:
                trading_pairs: List[str] = await self.get_trading_pairs()
                async with websockets.connect(OKEX_WS_URI_PUBLIC) as ws:
                    ws: websockets.WebSocketClientProtocol = ws

                    for trading_pair in trading_pairs:
                        subscribe_request: Dict[str, Any] = {
                            "op": "subscribe",
                            "args": [{
                                "channel": "books",
                                "instId": trading_pair
                            }]
                        }
                        await ws.send(json.dumps(subscribe_request))

                    async for raw_msg in self._inner_messages(ws):
                        decoded_msg: str = raw_msg

                        if '"event":"subscribe"' in decoded_msg:
                            self.logger().debug(
                                f"Subscribed to channel, full message: {decoded_msg}"
                            )
                        elif '"action":"update"' in decoded_msg:
                            msg = json.loads(decoded_msg)
                            for data in msg['data']:
                                order_book_message: OrderBookMessage = OkexOrderBook.diff_message_from_exchange(
                                    data, int(data['ts']), msg['arg'])
                                output.put_nowait(order_book_message)
                        else:
                            self.logger().debug(
                                f"Unrecognized message received from OKEx websocket: {decoded_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_order_book_snapshots(self,
                                           ev_loop: asyncio.BaseEventLoop,
                                           output: asyncio.Queue):
     """Fetches or Subscribes to the order book deltas(diffs) for each trading pair. Additionally, parses the incoming message into a OrderBookMessage and appends it into the output Queue."""
     while True:
         try:
             trading_pairs: List[str] = await self.get_trading_pairs()
             async with aiohttp.ClientSession() as client:
                 for trading_pair in trading_pairs:
                     try:
                         snapshot: Dict[str, Any] = await self.get_snapshot(
                             client, trading_pair)
                         snapshot_msg: OrderBookMessage = OkexOrderBook.snapshot_message_from_exchange(
                             snapshot,
                             trading_pair,
                             timestamp=snapshot['ts'],
                             metadata={"trading_pair": trading_pair})
                         output.put_nowait(snapshot_msg)
                         self.logger().debug(
                             f"Saved order book snapshot for {trading_pair}"
                         )
                         await asyncio.sleep(5.0)
                     except asyncio.CancelledError:
                         raise
                     except Exception:
                         self.logger().error("Unexpected error.",
                                             exc_info=True)
                         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)