def test_rest_api_url(self): endpoint = "/testEndpoint" url = utils.rest_api_url_for_endpoint(endpoint=endpoint, domain=None, ) self.assertEqual(CONSTANTS.REST_URLS.get("bybit_perpetual_main") + "/testEndpoint", url) url = utils.rest_api_url_for_endpoint(endpoint=endpoint, domain="bybit_perpetual_main") self.assertEqual(CONSTANTS.REST_URLS.get("bybit_perpetual_main") + "/testEndpoint", url) url = utils.rest_api_url_for_endpoint(endpoint=endpoint, domain="bybit_perpetual_testnet") self.assertEqual(CONSTANTS.REST_URLS.get("bybit_perpetual_testnet") + "/testEndpoint", url)
async def init_trading_pair_symbols( cls, domain: Optional[str] = None, throttler: Optional[AsyncThrottler] = None): """Initialize _trading_pair_symbol_map class variable """ cls._trading_pair_symbol_map[domain] = {} endpoint = CONSTANTS.QUERY_SYMBOL_ENDPOINT api_path = bybit_perpetual_utils.rest_api_path_for_endpoint( endpoint=endpoint) endpoint_url = bybit_perpetual_utils.rest_api_url_for_endpoint( endpoint=api_path, domain=domain) limit_id = bybit_perpetual_utils.get_rest_api_limit_id_for_endpoint( endpoint) throttler = throttler or cls._get_throttler_instance() async with aiohttp.ClientSession() as client: async with throttler.execute_task(limit_id): async with client.get(endpoint_url, params={}) as response: if response.status == 200: resp_json: Dict[str, Any] = await response.json() cls._trading_pair_symbol_map[domain] = { instrument["name"]: f"{instrument['base_currency']}-{instrument['quote_currency']}" for instrument in resp_json["result"] if (instrument["status"] == "Trading" and instrument["name"] == f"{instrument['base_currency']}{instrument['quote_currency']}" and bybit_perpetual_utils.is_linear_perpetual( f"{instrument['base_currency']}-{instrument['quote_currency']}" )) }
async def _get_last_traded_prices_from_exchange( cls, trading_pairs: List[str], domain: Optional[str] = None, throttler: Optional[AsyncThrottler] = None): result = {} trading_pair_symbol_map = await cls.trading_pair_symbol_map( domain=domain) endpoint = CONSTANTS.LATEST_SYMBOL_INFORMATION_ENDPOINT api_path = bybit_perpetual_utils.rest_api_path_for_endpoint(endpoint) endpoint_url = bybit_perpetual_utils.rest_api_url_for_endpoint( endpoint=api_path, domain=domain) limit_id = bybit_perpetual_utils.get_rest_api_limit_id_for_endpoint( endpoint) throttler = throttler or cls._get_throttler_instance(trading_pairs) async with aiohttp.ClientSession() as client: async with throttler.execute_task(limit_id): async with client.get(endpoint_url) as response: if response.status == 200: resp_json = await response.json() if "result" in resp_json: for token_pair_info in resp_json["result"]: token_pair = trading_pair_symbol_map.get( token_pair_info["symbol"]) if token_pair is not None and token_pair in trading_pairs: result[token_pair] = float( token_pair_info["last_price"]) return result
async def _get_funding_info_from_exchange( self, trading_pair: str) -> FundingInfo: symbol_map = await self.trading_pair_symbol_map(self._domain) symbols = [ symbol for symbol, pair in symbol_map.items() if trading_pair == pair ] if symbols: symbol = symbols[0] else: raise ValueError( f"There is no symbol mapping for trading pair {trading_pair}") params = {"symbol": symbol} funding_info = None endpoint = CONSTANTS.LATEST_SYMBOL_INFORMATION_ENDPOINT api_path = bybit_perpetual_utils.rest_api_path_for_endpoint( endpoint, trading_pair) url = bybit_perpetual_utils.rest_api_url_for_endpoint( endpoint=api_path, domain=self._domain) limit_id = bybit_perpetual_utils.get_rest_api_limit_id_for_endpoint( endpoint) session = await self._get_session() async with session as client: async with self._throttler.execute_task(limit_id): response = await client.get(url=url, params=params) if response.status == 200: resp_json = await response.json() symbol_info: Dict[str, Any] = ( resp_json["result"] [0] # Endpoint returns a List even though 1 entry is returned ) funding_info = FundingInfo( trading_pair=trading_pair, index_price=Decimal(str(symbol_info["index_price"])), mark_price=Decimal(str(symbol_info["mark_price"])), next_funding_utc_timestamp=int( pd.Timestamp( symbol_info["next_funding_time"]).timestamp()), rate=Decimal(str(symbol_info["predicted_funding_rate"]) ), # Note: no _e6 suffix from resp ) return funding_info
async def _get_order_book_data(self, trading_pair: str) -> Dict[str, any]: """Retrieves entire orderbook snapshot of the specified trading pair via the REST API. :param trading_pair: Trading pair of the particular orderbook. :return: Parsed API Response as a Json dictionary """ symbol_map = await self.trading_pair_symbol_map(self._domain) symbols = [ symbol for symbol, pair in symbol_map.items() if pair == trading_pair ] if symbols: symbol = symbols[0] else: raise ValueError( f"There is no symbol mapping for trading pair {trading_pair}") params = {"symbol": symbol} endpoint = CONSTANTS.ORDER_BOOK_ENDPOINT api_path = bybit_perpetual_utils.rest_api_path_for_endpoint( endpoint, trading_pair) url = bybit_perpetual_utils.rest_api_url_for_endpoint( endpoint=api_path, domain=self._domain) limit_id = bybit_perpetual_utils.get_rest_api_limit_id_for_endpoint( endpoint) session = await self._get_session() async with self._throttler.execute_task(limit_id): async with session.get(url, params=params) as response: status = response.status if status != 200: raise IOError( f"Error fetching OrderBook for {trading_pair} at {url}. " f"HTTP {status}. Response: {await response.json()}") response = await response.json() return response