예제 #1
0
    def test_get_last_traded_prices(self, mock_api):
        BybitAPIOrderBookDataSource._trading_pair_symbol_map[
            CONSTANTS.DEFAULT_DOMAIN]["TKN1TKN2"] = "TKN1-TKN2"

        url1 = web_utils.rest_url(path_url=CONSTANTS.LAST_TRADED_PRICE_PATH,
                                  domain=CONSTANTS.DEFAULT_DOMAIN)
        url1 = f"{url1}?symbol={self.ex_trading_pair}"
        regex_url = re.compile(f"^{url1}".replace(".",
                                                  r"\.").replace("?", r"\?"))
        resp = {
            "ret_code": 0,
            "ret_msg": None,
            "result": {
                "symbol": self.ex_trading_pair,
                "price": "50008"
            },
            "ext_code": None,
            "ext_info": None
        }
        mock_api.get(regex_url, body=json.dumps(resp))

        url2 = web_utils.rest_url(path_url=CONSTANTS.LAST_TRADED_PRICE_PATH,
                                  domain=CONSTANTS.DEFAULT_DOMAIN)
        url2 = f"{url2}?symbol=TKN1TKN2"
        regex_url = re.compile(f"^{url2}".replace(".",
                                                  r"\.").replace("?", r"\?"))
        resp = {
            "ret_code": 0,
            "ret_msg": None,
            "result": {
                "symbol": "TKN1TKN2",
                "price": "2050"
            },
            "ext_code": None,
            "ext_info": None
        }
        mock_api.get(regex_url, body=json.dumps(resp))

        ret = self.async_run_with_timeout(
            coroutine=BybitAPIOrderBookDataSource.get_last_traded_prices(
                [self.trading_pair, "TKN1-TKN2"]))

        ticker_requests = [(key, value)
                           for key, value in mock_api.requests.items()
                           if key[1].human_repr().startswith(url1)
                           or key[1].human_repr().startswith(url2)]
        request_params = ticker_requests[0][1][0].kwargs["params"]
        self.assertEqual(self.ex_trading_pair, request_params["symbol"])
        request_params = ticker_requests[1][1][0].kwargs["params"]
        self.assertEqual("TKN1TKN2", request_params["symbol"])

        self.assertEqual(ret[self.trading_pair], 50008)
        self.assertEqual(ret["TKN1-TKN2"], 2050)
예제 #2
0
    def test_listen_for_order_book_snapshots_log_exception(
            self, mock_api, sleep_mock):
        mock_queue = AsyncMock()
        mock_queue.get.side_effect = ['ERROR', asyncio.CancelledError]
        self.ob_data_source._message_queue[
            CONSTANTS.SNAPSHOT_EVENT_TYPE] = mock_queue

        msg_queue: asyncio.Queue = asyncio.Queue()
        sleep_mock.side_effect = [asyncio.CancelledError]
        url = web_utils.rest_url(path_url=CONSTANTS.SNAPSHOT_PATH_URL)
        regex_url = re.compile(f"^{url}".replace(".",
                                                 r"\.").replace("?", r"\?"))
        mock_api.get(regex_url, exception=Exception)

        try:
            self.async_run_with_timeout(
                self.ob_data_source.listen_for_order_book_snapshots(
                    self.ev_loop, msg_queue))
        except asyncio.CancelledError:
            pass

        self.assertTrue(
            self._is_logged(
                "ERROR",
                "Unexpected error when processing public order book updates from exchange"
            ))
예제 #3
0
    def test_get_snapshot_raises(self, mock_api):
        url = web_utils.rest_url(path_url=CONSTANTS.SNAPSHOT_PATH_URL)
        regex_url = re.compile(f"^{url}".replace(".",
                                                 r"\.").replace("?", r"\?"))
        mock_api.get(regex_url, status=500)

        with self.assertRaises(IOError):
            self.async_run_with_timeout(
                coroutine=self.ob_data_source.get_snapshot(self.trading_pair))
예제 #4
0
    def test_get_snapshot(self, mock_api):
        url = web_utils.rest_url(path_url=CONSTANTS.SNAPSHOT_PATH_URL)
        regex_url = re.compile(f"^{url}".replace(".",
                                                 r"\.").replace("?", r"\?"))
        snapshot_data = self._snapshot_response()
        mock_api.get(regex_url, body=json.dumps(snapshot_data))

        ret = self.async_run_with_timeout(
            coroutine=self.ob_data_source.get_snapshot(self.trading_pair))

        self.assertEqual(
            ret, self._snapshot_response_processed())  # shallow comparison ok
예제 #5
0
    def test_fetch_trading_pairs(self, mock_api):
        BybitAPIOrderBookDataSource._trading_pair_symbol_map = {}
        url = web_utils.rest_url(path_url=CONSTANTS.EXCHANGE_INFO_PATH_URL)

        resp = {
            "ret_code":
            0,
            "ret_msg":
            "",
            "ext_code":
            None,
            "ext_info":
            None,
            "result": [{
                "name": "BTCUSDT",
                "alias": "BTCUSDT",
                "baseCurrency": "BTC",
                "quoteCurrency": "USDT",
                "basePrecision": "0.000001",
                "quotePrecision": "0.01",
                "minTradeQuantity": "0.0001",
                "minTradeAmount": "10",
                "minPricePrecision": "0.01",
                "maxTradeQuantity": "2",
                "maxTradeAmount": "200",
                "category": 1
            }, {
                "name": "ETHUSDT",
                "alias": "ETHUSDT",
                "baseCurrency": "ETH",
                "quoteCurrency": "USDT",
                "basePrecision": "0.0001",
                "quotePrecision": "0.01",
                "minTradeQuantity": "0.0001",
                "minTradeAmount": "10",
                "minPricePrecision": "0.01",
                "maxTradeQuantity": "2",
                "maxTradeAmount": "200",
                "category": 1
            }]
        }
        mock_api.get(url, body=json.dumps(resp))

        ret = self.async_run_with_timeout(
            coroutine=BybitAPIOrderBookDataSource.fetch_trading_pairs(
                domain=self.domain,
                throttler=self.throttler,
                time_synchronizer=self.time_synchronnizer,
            ))
        self.assertEqual(2, len(ret))
        self.assertEqual("BTC-USDT", ret[0])
        self.assertEqual("ETH-USDT", ret[1])
예제 #6
0
    def test_fetch_trading_pairs_exception_raised(self, mock_api):
        BybitAPIOrderBookDataSource._trading_pair_symbol_map = {}

        url = web_utils.rest_url(path_url=CONSTANTS.EXCHANGE_INFO_PATH_URL)
        regex_url = re.compile(f"^{url}".replace(".",
                                                 r"\.").replace("?", r"\?"))

        mock_api.get(regex_url, exception=Exception)

        result: Dict[str] = self.async_run_with_timeout(
            self.ob_data_source.fetch_trading_pairs())

        self.assertEqual(0, len(result))
예제 #7
0
    def test_get_new_order_book(self, mock_api):
        url = web_utils.rest_url(path_url=CONSTANTS.SNAPSHOT_PATH_URL)
        regex_url = re.compile(f"^{url}".replace(".",
                                                 r"\.").replace("?", r"\?"))
        resp = self._snapshot_response()
        mock_api.get(regex_url, body=json.dumps(resp))

        ret = self.async_run_with_timeout(
            coroutine=self.ob_data_source.get_new_order_book(
                self.trading_pair))
        bid_entries = list(ret.bid_entries())
        ask_entries = list(ret.ask_entries())
        self.assertEqual(1, len(bid_entries))
        self.assertEqual(50005.12, bid_entries[0].price)
        self.assertEqual(403.0416, bid_entries[0].amount)
        self.assertEqual(int(resp["result"]["time"]), bid_entries[0].update_id)
        self.assertEqual(1, len(ask_entries))
        self.assertEqual(50006.34, ask_entries[0].price)
        self.assertEqual(0.2297, ask_entries[0].amount)
        self.assertEqual(int(resp["result"]["time"]), ask_entries[0].update_id)
예제 #8
0
    def test_listen_for_order_book_snapshots_successful_rest(
            self, mock_api, _):
        mock_queue = AsyncMock()
        mock_queue.get.side_effect = asyncio.TimeoutError
        self.ob_data_source._message_queue[
            CONSTANTS.SNAPSHOT_EVENT_TYPE] = mock_queue

        msg_queue: asyncio.Queue = asyncio.Queue()
        url = web_utils.rest_url(path_url=CONSTANTS.SNAPSHOT_PATH_URL)
        regex_url = re.compile(f"^{url}".replace(".",
                                                 r"\.").replace("?", r"\?"))
        snapshot_data = self._snapshot_response()
        mock_api.get(regex_url, body=json.dumps(snapshot_data))

        self.listening_task = self.ev_loop.create_task(
            self.ob_data_source.listen_for_order_book_snapshots(
                self.ev_loop, msg_queue))

        msg: OrderBookMessage = self.async_run_with_timeout(msg_queue.get())

        self.assertEqual(int(snapshot_data["result"]["time"]), msg.update_id)