Example #1
0
    async def listen_for_order_book_diffs(self, ev_loop: asyncio.BaseEventLoop, output: asyncio.Queue):
        while True:
            try:
                trading_pairs_full_list: List[str] = await self.get_trading_pairs()
                trading_pairs_partial_lists: List[List[str]] = [
                    trading_pairs_full_list[m: m + IDEX_WS_TRADING_PAIRS_SUBSCRIPTION_LIMIT] for m in
                    range(0, len(trading_pairs_full_list), IDEX_WS_TRADING_PAIRS_SUBSCRIPTION_LIMIT)]
                for trading_pairs in trading_pairs_partial_lists:
                    async with websockets.connect(IDEX_WS_URL) as ws:
                        ws: websockets.WebSocketClientProtocol = ws
                        await self._send_handshake(ws)
                        async for raw_message in self._inner_messages(ws):
                            decoded: Dict[str, Any] = ujson.loads(raw_message)
                            request: str = decoded.get("request")
                            diff_messages: List[Dict[str, Any]] = []
                            # after response from handshake, send subscribe message
                            if request == "handshake":
                                await self._send_subscribe(ws, trading_pairs, decoded)
                                continue

                            event: str = decoded.get("event")
                            payload: Dict[str, Any] = ujson.loads(decoded["payload"])  # payload is stringified json
                            if event == "market_orders":
                                orders: List[str, Any] = payload["orders"]
                                market: str = payload["market"]
                                diff_messages = [{**o, "event": event, "market": market} for o in orders]
                            elif event == "market_cancels":
                                cancels: List[str, Any] = payload["cancels"]
                                market: str = payload["market"]
                                diff_messages = [{**c, "event": event, "market": market} for c in cancels]
                            elif event == "market_trades":
                                trades: List[str, Any] = payload["trades"]
                                diff_messages = [{**t, "event": event} for t in trades]
                            else:
                                # ignore message if event is not recognized
                                continue
                            for diff_message in diff_messages:
                                ob_message: IDEXOrderBookMessage = IDEXOrderBook.diff_message_from_exchange(
                                    diff_message)
                                output.put_nowait(ob_message)
            except asyncio.CancelledError:
                raise
            except Exception:
                self.logger().network(
                    f"Error getting order book diff messages.",
                    exc_info=True,
                    app_warning_msg=f"Error getting order book diff messages. Check network connection."
                )
                await asyncio.sleep(30.0)
Example #2
0
 async def listen_for_order_book_snapshots(self,
                                           ev_loop: asyncio.BaseEventLoop,
                                           output: asyncio.Queue):
     await self._get_tracking_pair_done_event.wait()
     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_timestamp: float = time.time()
                         snapshot_msg: IDEXOrderBookMessage = IDEXOrderBook.snapshot_message_from_exchange(
                             snapshot, snapshot_timestamp,
                             {"market": trading_pair})
                         output.put_nowait(snapshot_msg)
                         self.logger().debug(
                             f"Saved order book snapshot for {trading_pair} at {snapshot_timestamp}"
                         )
                         await asyncio.sleep(5.0)
                     except asyncio.CancelledError:
                         raise
                     except Exception:
                         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."
                         )
                         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().network(
                 f"Unexpected error listening for order book snapshot.",
                 exc_info=True,
                 app_warning_msg=
                 f"Unexpected error listening for order book snapshot. Check network connection."
             )
             await asyncio.sleep(5.0)
Example #3
0
    async def get_tracking_pairs(self) -> Dict[str, OrderBookTrackerEntry]:
        # Get the currently active markets
        async with aiohttp.ClientSession() as client:
            trading_pairs: List[str] = await self.get_trading_pairs()
            retval: Dict[str, IDEXOrderBookTrackerEntry] = {}
            number_of_pairs: int = len(trading_pairs)
            token_info: Dict[str, Dict[str,
                                       Any]] = await self.get_all_token_info()
            for index, trading_pair in enumerate(trading_pairs):
                try:
                    snapshot: Dict[str, any] = await self.get_snapshot(
                        client, trading_pair)
                    snapshot_msg: IDEXOrderBookMessage = IDEXOrderBook.snapshot_message_from_exchange(
                        msg=snapshot,
                        timestamp=None,
                        metadata={"market": trading_pair})
                    quote_asset_symbol, base_asset_symbol = trading_pair.split(
                        "_")
                    base_asset: Dict[str, Any] = token_info[base_asset_symbol]
                    quote_asset: Dict[str,
                                      Any] = token_info[quote_asset_symbol]
                    idex_active_order_tracker: IDEXActiveOrderTracker = IDEXActiveOrderTracker(
                        base_asset=base_asset, quote_asset=quote_asset)
                    bids, asks = idex_active_order_tracker.convert_snapshot_message_to_order_book_row(
                        snapshot_msg)
                    snapshot_timestamp: float = idex_active_order_tracker.latest_snapshot_timestamp
                    idex_order_book: OrderBook = self.order_book_create_function(
                    )
                    idex_order_book.apply_snapshot(bids, asks,
                                                   snapshot_timestamp)
                    retval[trading_pair] = IDEXOrderBookTrackerEntry(
                        trading_pair, snapshot_timestamp, idex_order_book,
                        idex_active_order_tracker)

                    self.logger().info(
                        f"Initialized order book for {trading_pair}. "
                        f"{index+1}/{number_of_pairs} completed.")
                    await asyncio.sleep(1.0)
                except Exception:
                    self.logger().error(
                        f"Error initializing order book for {trading_pair}.",
                        exc_info=True)
                    await asyncio.sleep(5)

            self._get_tracking_pair_done_event.set()
            return retval