예제 #1
0
 async def _collect_and_decode_messages_loop(self, stream_type: StreamType,
                                             task_index: int,
                                             output: asyncio.Queue):
     while True:
         try:
             kucoin_msg_iterator: KucoinWSConnectionIterator = KucoinWSConnectionIterator(
                 stream_type,
                 self._tasks[stream_type][task_index].trading_pairs,
                 self._throttler)
             self._tasks[stream_type][
                 task_index].message_iterator = kucoin_msg_iterator
             async for raw_msg in kucoin_msg_iterator:
                 msg_type: str = raw_msg.get("type", "")
                 if msg_type in {"ack", "welcome", "pong"}:
                     pass
                 elif msg_type == "message":
                     if stream_type == StreamType.Depth:
                         order_book_message: OrderBookMessage = KucoinOrderBook.diff_message_from_exchange(
                             raw_msg)
                     else:
                         trading_pair: str = convert_to_exchange_trading_pair(
                             raw_msg["data"]["symbol"])
                         data = raw_msg["data"]
                         order_book_message: OrderBookMessage = \
                             KucoinOrderBook.trade_message_from_exchange(
                                 data,
                                 metadata={"trading_pair": trading_pair}
                             )
                     output.put_nowait(order_book_message)
                 elif msg_type == "error":
                     self.logger().error(
                         f"WS error message from Kucoin: {raw_msg}")
                 else:
                     self.logger().warning(
                         f"Unrecognized message type from Kucoin: {msg_type}. "
                         f"Message = {raw_msg}.")
         except asyncio.CancelledError:
             raise
         except asyncio.TimeoutError:
             self.logger().error(
                 "Timeout error with WebSocket connection. Retrying after 5 seconds...",
                 exc_info=True)
             await asyncio.sleep(5.0)
         except Exception:
             self.logger().error(
                 "Unexpected exception with WebSocket connection. Retrying after 5 seconds...",
                 exc_info=True)
             await asyncio.sleep(5.0)
         finally:
             if stream_type in self._tasks:
                 if task_index in self._tasks:
                     self._tasks[stream_type][
                         task_index].message_iterator = None
예제 #2
0
 async def listen_for_order_book_snapshots(self, ev_loop: asyncio.BaseEventLoop, output: asyncio.Queue):
     while True:
         try:
             trading_pairs: List[str] = self._trading_pairs if self._trading_pairs else await self.fetch_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_timestamp: float = time.time()
                         snapshot_msg: OrderBookMessage = KucoinOrderBook.snapshot_message_from_exchange(
                             snapshot,
                             snapshot_timestamp,
                             metadata={"symbol": trading_pair}
                         )
                         output.put_nowait(snapshot_msg)
                         self.logger().debug(f"Saved order book snapshot for {trading_pair}")
                         await asyncio.sleep(self.SLEEP_BETWEEN_SNAPSHOT_REQUEST)
                     except asyncio.CancelledError:
                         raise
                     except Exception:
                         self.logger().error("Unexpected error.", exc_info=True)
                         await asyncio.sleep(5.0)
             await asyncio.sleep(secs_until_next_oclock())
         except asyncio.CancelledError:
             raise
         except Exception:
             self.logger().error("Unexpected error.", exc_info=True)
             await asyncio.sleep(5.0)
예제 #3
0
    async def listen_for_order_book_diffs(self,
                                          ev_loop: asyncio.AbstractEventLoop,
                                          output: asyncio.Queue):
        """
        Reads the order diffs events queue. For each event creates a diff 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 diff messages
        """
        message_queue = self._message_queue[CONSTANTS.DIFF_EVENT_TYPE]
        while True:
            try:
                json_msg = await message_queue.get()

                trading_pair = await self.trading_pair_associated_to_exchange_symbol(
                    symbol=json_msg["data"]["symbol"],
                    domain=self._domain,
                    api_factory=self._api_factory,
                    throttler=self._throttler)
                order_book_message: OrderBookMessage = KucoinOrderBook.diff_message_from_exchange(
                    json_msg, self._time(), {"trading_pair": trading_pair})
                output.put_nowait(order_book_message)
            except asyncio.CancelledError:
                raise
            except Exception:
                self.logger().exception(
                    "Unexpected error when processing public order book updates from exchange"
                )
예제 #4
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_timestamp: float = time.time()
         snapshot_msg: OrderBookMessage = KucoinOrderBook.snapshot_message_from_exchange(
             snapshot,
             snapshot_timestamp,
             metadata={"symbol": trading_pair}
         )
         order_book: OrderBook = self.order_book_create_function()
         active_order_tracker: KucoinActiveOrderTracker = KucoinActiveOrderTracker()
         bids, asks = active_order_tracker.convert_snapshot_message_to_order_book_row(snapshot_msg)
         order_book.apply_snapshot(bids, asks, snapshot_msg.update_id)
         return order_book
예제 #5
0
    async def get_new_order_book(self, trading_pair: str) -> OrderBook:
        """
        Creates a local instance of the exchange order book for a particular trading pair

        :param trading_pair: the trading pair for which the order book has to be retrieved

        :return: a local copy of the current order book in the exchange
        """
        snapshot: Dict[str, Any] = await self.get_snapshot(trading_pair)
        snapshot_timestamp: float = snapshot["data"]["time"] * 1e-3
        snapshot_msg: OrderBookMessage = KucoinOrderBook.snapshot_message_from_exchange(
            snapshot,
            snapshot_timestamp,
            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
예제 #6
0
 async def _take_full_order_book_snapshot(self, trading_pairs: List[str],
                                          snapshot_queue: asyncio.Queue):
     for trading_pair in trading_pairs:
         try:
             snapshot: Dict[str, Any] = await self.get_snapshot(
                 trading_pair=trading_pair)
             snapshot_timestamp = float(snapshot["data"]["time"]) * 1e-3
             snapshot_msg: OrderBookMessage = KucoinOrderBook.snapshot_message_from_exchange(
                 snapshot,
                 snapshot_timestamp,
                 metadata={"trading_pair": trading_pair})
             snapshot_queue.put_nowait(snapshot_msg)
             self.logger().debug(
                 f"Saved order book snapshot for {trading_pair}")
         except asyncio.CancelledError:
             raise
         except Exception:
             self.logger().error(
                 f"Unexpected error fetching order book snapshot for {trading_pair}.",
                 exc_info=True)
    async def listen_for_trades(self, ev_loop: asyncio.BaseEventLoop,
                                output: asyncio.Queue):
        websocket_data: Dict[str, Any] = await self.ws_connect_data()
        kucoin_ws_uri: str = websocket_data["data"]["instanceServers"][0][
            "endpoint"] + "?token=" + websocket_data["data"][
                "token"] + "&acceptUserMessage=true"
        while True:
            try:
                async with websockets.connect(kucoin_ws_uri) as ws:
                    ws: websockets.WebSocketClientProtocol = ws
                    for trading_pair in self._trading_pairs:
                        subscribe_request: Dict[str, Any] = {
                            "id": int(time.time()),
                            "type": "subscribe",
                            "topic": f"/market/match:{trading_pair}",
                            "privateChannel": False,
                            "response": True
                        }
                        await ws.send(json.dumps(subscribe_request))

                    async for raw_msg in self._inner_messages(ws):
                        msg: Dict[str, Any] = json.loads(raw_msg)
                        if msg["type"] == "pong" or msg["type"] == "ack":
                            pass
                        elif msg["type"] == "message":
                            trading_pair = msg["data"]["symbol"]
                            data = msg["data"]
                            trade_message: OrderBookMessage = KucoinOrderBook.trade_message_from_exchange(
                                data, metadata={"trading_pair": trading_pair})
                            output.put_nowait(trade_message)
                        else:
                            self.logger().debug(
                                f"Unrecognized message received from Kucoin websocket: {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):
     while True:
         try:
             async with aiohttp.ClientSession() as client:
                 for trading_pair in self._trading_pairs:
                     try:
                         snapshot: Dict[str, Any] = await self.get_snapshot(
                             client, trading_pair)
                         snapshot_timestamp: float = time.time()
                         snapshot_msg: OrderBookMessage = KucoinOrderBook.snapshot_message_from_exchange(
                             snapshot,
                             snapshot_timestamp,
                             metadata={"symbol": 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)