async def listen_for_order_book_snapshots(self, ev_loop: asyncio.BaseEventLoop, output: asyncio.Queue):
        while True:
            try:
                # at Beaxy all pairs listed without splitter
                trading_pairs = [trading_pair_to_symbol(p) for p in self._trading_pairs]

                ws_path: str = '/'.join([f'{trading_pair}@depth20' for trading_pair in trading_pairs])
                stream_url: str = f'{BeaxyConstants.PublicApi.WS_BASE_URL}/book/{ws_path}'

                async with websockets.connect(stream_url) as ws:
                    ws: websockets.WebSocketClientProtocol = ws
                    async for raw_msg in self._inner_messages(ws):
                        msg = json.loads(raw_msg)  # ujson may round floats uncorrectly
                        msg_type = msg['type']
                        if msg_type == ORDERBOOK_MESSAGE_DIFF:
                            order_book_message: OrderBookMessage = BeaxyOrderBook.diff_message_from_exchange(
                                msg, msg['timestamp'])
                            output.put_nowait(order_book_message)
                        if msg_type == ORDERBOOK_MESSAGE_SNAPSHOT:
                            order_book_message: OrderBookMessage = BeaxyOrderBook.snapshot_message_from_exchange(
                                msg, msg['timestamp'])
                            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)
Пример #2
0
    def test_delete_through(self):
        active_tracker = BeaxyActiveOrderTracker()

        # receive INSERT message to be added to active orders
        first_insert: Dict[str, Any] = {
            'timestamp': 1,
            "sequenceNumber": 1,
            'entries': [{
                "action": "INSERT",
                "quantity": 1,
                "price": 133,
                "side": "BID",
                "sequrity": test_trading_pair,
            }]
        }
        second_insert: Dict[str, Any] = {
            'timestamp': 1,
            "sequenceNumber": 2,
            'entries': [{
                "action": "INSERT",
                "quantity": 2,
                "price": 134,
                "side": "BID",
                "sequrity": test_trading_pair
            }]
        }
        third_insert: Dict[str, Any] = {
            'timestamp': 1,
            "sequenceNumber": 1,
            'entries': [{
                "action": "INSERT",
                "quantity": 3,
                "price": 135,
                "side": "BID",
                "sequrity": test_trading_pair
            }]
        }

        inserts = [first_insert, second_insert, third_insert]
        for msg in inserts:
            insert_message = BeaxyOrderBook.diff_message_from_exchange(msg, float(12345))
            active_tracker.convert_diff_message_to_order_book_row(insert_message)

        delete_through_dict: Dict[str, Any] = {
            'timestamp': 1,
            "sequenceNumber": 1,
            'entries': [{
                "action": "DELETE_THROUGH",
                "quantity": 3,
                "price": 134,
                "side": "BID",
                "sequrity": test_trading_pair
            }]
        }

        msg = BeaxyOrderBook.diff_message_from_exchange(delete_through_dict, float(12345))
        active_tracker.convert_diff_message_to_order_book_row(msg)
        self.assertEqual(len(active_tracker.active_bids), 2)
        self.assertEqual(next(iter(active_tracker.active_bids)), 134)
Пример #3
0
    def test_insert_update_delete_messages(self):
        active_tracker = BeaxyActiveOrderTracker()

        # receive INSERT message to be added to active orders
        side = "BID"
        price = 1337.4423423404
        quantity: float = 1
        update_id = 123
        message_dict: Dict[str, Any] = {
            'timestamp': 1,
            'sequenceNumber': update_id,
            'entries': [{
                "action": "INSERT",
                "quantity": quantity,
                "price": price,
                "side": side,
                "sequrity": test_trading_pair
            }]
        }
        insert_message = BeaxyOrderBook.diff_message_from_exchange(message_dict, float(12345))
        insert_ob_row: OrderBookRow = active_tracker.convert_diff_message_to_order_book_row(insert_message)
        self.assertEqual(insert_ob_row[0], [OrderBookRow(price, quantity, update_id)])

        # receive UPDATE message
        updated_quantity: float = 3.2
        update_message_dict: Dict[str, Any] = {
            'timestamp': 1,
            "sequenceNumber": update_id + 1,
            'entries': [{
                "action": "UPDATE",
                "quantity": updated_quantity,
                "price": price,
                "side": side,
                "sequrity": test_trading_pair
            }]
        }
        change_message = BeaxyOrderBook.diff_message_from_exchange(update_message_dict, float(12345))
        change_ob_row: OrderBookRow = active_tracker.convert_diff_message_to_order_book_row(change_message)
        self.assertEqual(change_ob_row[0], [OrderBookRow(price, float(updated_quantity), update_id + 1)])

        # receive DELETE message
        delete_quantity = 1
        delete_message_dict: Dict[str, Any] = {
            'timestamp': 1,
            "sequenceNumber": update_id + 2,
            'entries': [{
                "action": "DELETE",
                "quantity": delete_quantity,
                "price": price,
                "side": side,
                "sequrity": test_trading_pair
            }]
        }

        delete_message: BeaxyOrderBookMessage = BeaxyOrderBook.diff_message_from_exchange(delete_message_dict, float(12345))
        delete_ob_row: OrderBookRow = active_tracker.convert_diff_message_to_order_book_row(delete_message)
        self.assertEqual(delete_ob_row[0], [OrderBookRow(price, float(0), update_id + 1 + 1)])
    async def listen_for_trades(self, ev_loop: asyncio.BaseEventLoop,
                                output: asyncio.Queue):
        while True:
            try:
                # at Beaxy all pairs listed without splitter
                trading_pairs = [
                    trading_pair_to_symbol(p) for p in self._trading_pairs
                ]

                ws_path: str = '/'.join(
                    [trading_pair for trading_pair in trading_pairs])
                stream_url: str = f'{BeaxyConstants.PublicApi.WS_BASE_URL}/trades/{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 = BeaxyOrderBook.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 get_tracking_pairs(self) -> Dict[str, OrderBookTrackerEntry]:
        async with aiohttp.ClientSession() as client:
            trading_pairs: Optional[List[str]] = await self.get_trading_pairs()
            assert trading_pairs is not None
            retval: Dict[str, OrderBookTrackerEntry] = {}
            number_of_pairs: int = len(trading_pairs)
            for index, trading_pair in enumerate(trading_pairs):
                try:
                    snapshot: Dict[str, Any] = await self.get_snapshot(
                        client, trading_pair, 20)
                    snapshot_timestamp = snapshot['timestamp']
                    snapshot_msg: OrderBookMessage = BeaxyOrderBook.snapshot_message_from_exchange(
                        snapshot,
                        snapshot_timestamp,
                        metadata={'trading_pair': trading_pair})
                    order_book: OrderBook = self.order_book_create_function()
                    active_order_tracker: BeaxyActiveOrderTracker = BeaxyActiveOrderTracker(
                    )
                    bids, asks = active_order_tracker.convert_snapshot_message_to_order_book_row(
                        snapshot_msg)
                    order_book.apply_snapshot(bids, asks,
                                              snapshot_msg.update_id)
                    retval[trading_pair] = BeaxyOrderBookTrackerEntry(
                        trading_pair, snapshot_timestamp, order_book,
                        active_order_tracker)

                    self.logger().info(
                        f'Initialized order book for {trading_pair}. '
                        f'{index+1}/{number_of_pairs} completed.')
                except Exception:
                    self.logger().error(
                        f'Error getting snapshot for {trading_pair}. ',
                        exc_info=True)
                    await asyncio.sleep(5.0)
            return retval
Пример #6
0
    def test_snapshot(self):
        active_tracker = BeaxyActiveOrderTracker()
        insert_message = BeaxyOrderBook.snapshot_message_from_exchange(FixtureBeaxy.SNAPSHOT_MSG, float(12345))

        active_tracker.convert_snapshot_message_to_order_book_row(insert_message)

        self.assertEqual(len(active_tracker.active_asks), 9)
 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, 20)
         snapshot_timestamp = snapshot['timestamp']
         snapshot_msg: OrderBookMessage = BeaxyOrderBook.snapshot_message_from_exchange(
             snapshot,
             snapshot_timestamp,
             metadata={'trading_pair': trading_pair}
         )
         order_book: OrderBook = self.order_book_create_function()
         active_order_tracker: BeaxyActiveOrderTracker = BeaxyActiveOrderTracker()
         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