예제 #1
0
    def test_track_single_book_diff_message(self, mock_utils):
        # Mocks binance_utils for BinanceOrderBook.diff_message_from_exchange()
        mock_utils.return_value = self.trading_pair
        diff_msg: OrderBookMessage = BinanceOrderBook.diff_message_from_exchange(
            msg={
                "e": "depthUpdate",
                "E": 123456789,
                "s": "BNBBTC",
                "U": 1,
                "u": 2,
                "b": [
                    [
                        "0.0024",
                        "10"
                    ]
                ],
                "a": [
                    [
                        "0.0026",
                        "100"
                    ]
                ]
            }
        )

        self._simulate_message_enqueue(self.tracker._tracking_message_queues[self.trading_pair], diff_msg)

        self.tracking_task = self.ev_loop.create_task(
            self.tracker._track_single_book(self.trading_pair)
        )
        self.ev_loop.run_until_complete(asyncio.sleep(0.5))

        self.assertEqual(0, self.tracker.order_books[self.trading_pair].snapshot_uid)
        self.assertEqual(2, self.tracker.order_books[self.trading_pair].last_diff_uid)
    async def listen_for_order_book_diffs(self, ev_loop: asyncio.BaseEventLoop,
                                          output: asyncio.Queue):
        while True:
            try:
                ws_path: str = "/".join([
                    f"{convert_to_exchange_trading_pair(trading_pair).lower()}@depth"
                    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)
                        order_book_message: OrderBookMessage = BinanceOrderBook.diff_message_from_exchange(
                            msg, time.time())
                        output.put_nowait(order_book_message)
            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_diffs(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()}@depth"
                        for trading_pair in self._trading_pairs
                    ],
                    "id":
                    self.DIFF_STREAM_ID
                }
                await ws.send_json(payload)

                async for json_msg in self._iter_messages(ws):
                    if "result" in json_msg:
                        continue
                    order_book_message: OrderBookMessage = BinanceOrderBook.diff_message_from_exchange(
                        json_msg, time.time())
                    output.put_nowait(order_book_message)
            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)
예제 #4
0
    def test_diff_message_from_exchange(self):
        diff_msg = BinanceOrderBook.diff_message_from_exchange(
            msg={
                "e": "depthUpdate",
                "E": 123456789,
                "s": "COINALPHAHBOT",
                "U": 1,
                "u": 2,
                "b": [["0.0024", "10"]],
                "a": [["0.0026", "100"]]
            },
            timestamp=1640000000.0,
            metadata={"trading_pair": "COINALPHA-HBOT"})

        self.assertEqual("COINALPHA-HBOT", diff_msg.trading_pair)
        self.assertEqual(OrderBookMessageType.DIFF, diff_msg.type)
        self.assertEqual(1640000000.0, diff_msg.timestamp)
        self.assertEqual(2, diff_msg.update_id)
        self.assertEqual(1, diff_msg.first_update_id)
        self.assertEqual(-1, diff_msg.trade_id)
        self.assertEqual(1, len(diff_msg.bids))
        self.assertEqual(0.0024, diff_msg.bids[0].price)
        self.assertEqual(10.0, diff_msg.bids[0].amount)
        self.assertEqual(2, diff_msg.bids[0].update_id)
        self.assertEqual(1, len(diff_msg.asks))
        self.assertEqual(0.0026, diff_msg.asks[0].price)
        self.assertEqual(100.0, diff_msg.asks[0].amount)
        self.assertEqual(2, diff_msg.asks[0].update_id)
 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()
             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)
             order_book_message: OrderBookMessage = BinanceOrderBook.diff_message_from_exchange(
                 json_msg, time.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"
             )
 async def _parse_order_book_diff_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"])
         order_book_message: OrderBookMessage = BinanceOrderBook.diff_message_from_exchange(
             raw_message, time.time(), {"trading_pair": trading_pair})
         message_queue.put_nowait(order_book_message)
예제 #7
0
    def test_track_single_book_snapshot_message_with_past_diffs(self, mock_utils):
        # Mocks binance_utils for BinanceOrderBook.diff_message_from_exchange()
        mock_utils.return_value = self.trading_pair
        snapshot_msg: OrderBookMessage = BinanceOrderBook.snapshot_message_from_exchange(
            msg={
                "trading_pair": self.trading_pair,
                "lastUpdateId": 1,
                "bids": [
                    ["4.00000000", "431.00000000"]
                ],
                "asks": [
                    ["4.00000200", "12.00000000"]
                ]
            },
            timestamp=time.time()
        )
        past_diff_msg: OrderBookMessage = BinanceOrderBook.diff_message_from_exchange(
            msg={
                "e": "depthUpdate",
                "E": 123456789,
                "s": "BNBBTC",
                "U": 1,
                "u": 2,
                "b": [
                    [
                        "0.0024",
                        "10"
                    ]
                ],
                "a": [
                    [
                        "0.0026",
                        "100"
                    ]
                ]
            }
        )

        self.tracking_task = self.ev_loop.create_task(
            self.tracker._track_single_book(self.trading_pair)
        )

        self.ev_loop.run_until_complete(asyncio.sleep(0.5))

        self._simulate_message_enqueue(self.tracker._past_diffs_windows[self.trading_pair], past_diff_msg)
        self._simulate_message_enqueue(self.tracker._tracking_message_queues[self.trading_pair], snapshot_msg)

        self.ev_loop.run_until_complete(asyncio.sleep(0.5))

        self.assertEqual(1, self.tracker.order_books[self.trading_pair].snapshot_uid)
        self.assertEqual(2, self.tracker.order_books[self.trading_pair].last_diff_uid)