From 954e733a99aae4dbd50db0fae523492bfaff8cfb Mon Sep 17 00:00:00 2001 From: discosultan Date: Wed, 21 Feb 2024 20:21:22 +0100 Subject: [PATCH 1/9] (fix) use correct pairs in simple xemm example exchange dataframe --- scripts/simple_xemm_example.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/simple_xemm_example.py b/scripts/simple_xemm_example.py index 3c8244b453..f1daac3834 100644 --- a/scripts/simple_xemm_example.py +++ b/scripts/simple_xemm_example.py @@ -119,8 +119,8 @@ def exchanges_df(self) -> pd.DataFrame: Return a custom data frame of prices on maker vs taker exchanges for display purposes """ mid_price = self.connectors[self.maker_exchange].get_mid_price(self.maker_pair) - maker_buy_result = self.connectors[self.maker_exchange].get_price_for_volume(self.taker_pair, True, self.order_amount) - maker_sell_result = self.connectors[self.maker_exchange].get_price_for_volume(self.taker_pair, False, self.order_amount) + maker_buy_result = self.connectors[self.maker_exchange].get_price_for_volume(self.maker_pair, True, self.order_amount) + maker_sell_result = self.connectors[self.maker_exchange].get_price_for_volume(self.maker_pair, False, self.order_amount) taker_buy_result = self.connectors[self.taker_exchange].get_price_for_volume(self.taker_pair, True, self.order_amount) taker_sell_result = self.connectors[self.taker_exchange].get_price_for_volume(self.taker_pair, False, self.order_amount) maker_buy_spread_bps = (maker_buy_result.result_price - taker_buy_result.result_price) / mid_price * 10000 @@ -139,7 +139,7 @@ def exchanges_df(self) -> pd.DataFrame: data.append([ self.taker_exchange, self.taker_pair, - float(self.connectors[self.taker_exchange].get_mid_price(self.maker_pair)), + float(self.connectors[self.taker_exchange].get_mid_price(self.taker_pair)), float(taker_buy_result.result_price), float(taker_sell_result.result_price), int(-maker_buy_spread_bps), From 91c5fe9eebe3e6b1e0a005f46790737f03c80b56 Mon Sep 17 00:00:00 2001 From: Ralph Comia Date: Wed, 20 Mar 2024 21:01:39 +0800 Subject: [PATCH 2/9] update hummingbot version and release date --- hummingbot/VERSION | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hummingbot/VERSION b/hummingbot/VERSION index cfba14e17c..5ff8c4f5d2 100644 --- a/hummingbot/VERSION +++ b/hummingbot/VERSION @@ -1 +1 @@ -dev-1.26.0 +1.26.0 diff --git a/setup.py b/setup.py index 67f6c9831e..891f37a540 100644 --- a/setup.py +++ b/setup.py @@ -33,7 +33,7 @@ def build_extensions(self): def main(): cpu_count = os.cpu_count() or 8 - version = "20240226" + version = "20240325" all_packages = find_packages(include=["hummingbot", "hummingbot.*"], ) excluded_paths = [ "hummingbot.connector.gateway.clob_spot.data_sources.injective", From 034584c2493acecb412c0beb1650e4e9a6d16387 Mon Sep 17 00:00:00 2001 From: mlguys Date: Thu, 25 Apr 2024 16:44:16 +0700 Subject: [PATCH 3/9] Fix new api update from binance --- .../connector/exchange/binance/binance_utils.py | 15 ++++++++++++++- .../rate_oracle/sources/binance_rate_source.py | 4 ++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/hummingbot/connector/exchange/binance/binance_utils.py b/hummingbot/connector/exchange/binance/binance_utils.py index b0e47c4da0..6b3676066d 100644 --- a/hummingbot/connector/exchange/binance/binance_utils.py +++ b/hummingbot/connector/exchange/binance/binance_utils.py @@ -22,7 +22,20 @@ def is_exchange_information_valid(exchange_info: Dict[str, Any]) -> bool: :param exchange_info: the exchange information for a trading pair :return: True if the trading pair is enabled, False otherwise """ - return exchange_info.get("status", None) == "TRADING" and "SPOT" in exchange_info.get("permissions", list()) + is_spot = False + is_trading = False + + if exchange_info.get("status", None) == "TRADING": + is_trading = True + + permissions_sets = exchange_info.get("permissionSets", list()) + for permission_set in permissions_sets: + # PermissionSet is a list, find if in this list we have "SPOT" value or not + if "SPOT" in permission_set: + is_spot = True + break + + return is_trading and is_spot class BinanceConfigMap(BaseConnectorConfigMap): diff --git a/hummingbot/core/rate_oracle/sources/binance_rate_source.py b/hummingbot/core/rate_oracle/sources/binance_rate_source.py index 5aa65805c4..5d7ceb1627 100644 --- a/hummingbot/core/rate_oracle/sources/binance_rate_source.py +++ b/hummingbot/core/rate_oracle/sources/binance_rate_source.py @@ -26,7 +26,7 @@ async def get_prices(self, quote_token: Optional[str] = None) -> Dict[str, Decim results = {} tasks = [ self._get_binance_prices(exchange=self._binance_exchange), - self._get_binance_prices(exchange=self._binance_us_exchange, quote_token="USD"), + # self._get_binance_prices(exchange=self._binance_us_exchange, quote_token="USD"), ] task_results = await safe_gather(*tasks, return_exceptions=True) for task_result in task_results: @@ -43,7 +43,7 @@ async def get_prices(self, quote_token: Optional[str] = None) -> Dict[str, Decim def _ensure_exchanges(self): if self._binance_exchange is None: self._binance_exchange = self._build_binance_connector_without_private_keys(domain="com") - self._binance_us_exchange = self._build_binance_connector_without_private_keys(domain="us") + # self._binance_us_exchange = self._build_binance_connector_without_private_keys(domain="us") @staticmethod async def _get_binance_prices(exchange: 'BinanceExchange', quote_token: str = None) -> Dict[str, Decimal]: From ae3a68100748fc7de223863c1a448feeab553e58 Mon Sep 17 00:00:00 2001 From: mlguys Date: Thu, 25 Apr 2024 16:46:39 +0700 Subject: [PATCH 4/9] disable binance_us in rate oracle --- hummingbot/core/rate_oracle/sources/binance_rate_source.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hummingbot/core/rate_oracle/sources/binance_rate_source.py b/hummingbot/core/rate_oracle/sources/binance_rate_source.py index 5d7ceb1627..7dd7e13190 100644 --- a/hummingbot/core/rate_oracle/sources/binance_rate_source.py +++ b/hummingbot/core/rate_oracle/sources/binance_rate_source.py @@ -14,7 +14,7 @@ class BinanceRateSource(RateSourceBase): def __init__(self): super().__init__() self._binance_exchange: Optional[BinanceExchange] = None # delayed because of circular reference - self._binance_us_exchange: Optional[BinanceExchange] = None # delayed because of circular reference + # self._binance_us_exchange: Optional[BinanceExchange] = None # delayed because of circular reference @property def name(self) -> str: From fd924c2239295482ed43ab8b42c1e81ce7137060 Mon Sep 17 00:00:00 2001 From: mlguys Date: Thu, 25 Apr 2024 17:08:16 +0700 Subject: [PATCH 5/9] update test cases --- .../exchange/binance/test_binance_exchange.py | 34 +++++++++---------- .../exchange/binance/test_binance_utils.py | 8 ++--- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/test/hummingbot/connector/exchange/binance/test_binance_exchange.py b/test/hummingbot/connector/exchange/binance/test_binance_exchange.py index 37fd9b979b..3d713bcf68 100644 --- a/test/hummingbot/connector/exchange/binance/test_binance_exchange.py +++ b/test/hummingbot/connector/exchange/binance/test_binance_exchange.py @@ -84,10 +84,10 @@ def all_symbols_request_mock_response(self): "isSpotTradingAllowed": True, "isMarginTradingAllowed": True, "filters": [], - "permissions": [ + "permissionSets": [[ "SPOT", "MARGIN" - ] + ]] }, ] } @@ -149,9 +149,9 @@ def all_symbols_including_invalid_pair_mock_response(self) -> Tuple[str, Any]: "isSpotTradingAllowed": True, "isMarginTradingAllowed": True, "filters": [], - "permissions": [ + "permissionSets": [[ "MARGIN" - ] + ]] }, { "symbol": self.exchange_symbol_for_tokens("INVALID", "PAIR"), @@ -176,9 +176,9 @@ def all_symbols_including_invalid_pair_mock_response(self) -> Tuple[str, Any]: "isSpotTradingAllowed": True, "isMarginTradingAllowed": True, "filters": [], - "permissions": [ + "permissionSets": [[ "MARGIN" - ] + ]] }, ] } @@ -226,10 +226,10 @@ def trading_rules_request_mock_response(self): "minNotional": "0.00100000" } ], - "permissions": [ + "permissionSets": [[ "SPOT", "MARGIN" - ] + ]] } ] } @@ -255,10 +255,10 @@ def trading_rules_request_erroneous_mock_response(self): "ocoAllowed": True, "isSpotTradingAllowed": True, "isMarginTradingAllowed": True, - "permissions": [ + "permissionSets": [[ "SPOT", "MARGIN" - ] + ]] } ] } @@ -297,9 +297,9 @@ def balance_request_mock_response_for_base_and_quote(self): "locked": "0.00000000" } ], - "permissions": [ + "permissionSets": [[ "SPOT" - ] + ]] } @property @@ -315,7 +315,7 @@ def balance_request_mock_response_only_base(self): "updateTime": 123456789, "accountType": "SPOT", "balances": [{"asset": self.base_asset, "free": "10.0", "locked": "5.0"}], - "permissions": ["SPOT"], + "permissionSets": [["SPOT"]], } @property @@ -1180,9 +1180,9 @@ def test_format_trading_rules__min_notional_present(self): "minNotional": "0.00100000" } ], - "permissions": [ + "permissionSets": [[ "SPOT" - ] + ]] }] exchange_info = {"symbols": trading_rules} @@ -1217,9 +1217,9 @@ def test_format_trading_rules__notional_but_no_min_notional_present(self): "avgPriceMins": 5 } ], - "permissions": [ + "permissionSets": [[ "SPOT" - ] + ]] }] exchange_info = {"symbols": trading_rules} diff --git a/test/hummingbot/connector/exchange/binance/test_binance_utils.py b/test/hummingbot/connector/exchange/binance/test_binance_utils.py index 40c9666bd5..4ab8c14fa5 100644 --- a/test/hummingbot/connector/exchange/binance/test_binance_utils.py +++ b/test/hummingbot/connector/exchange/binance/test_binance_utils.py @@ -17,28 +17,28 @@ def setUpClass(cls) -> None: def test_is_exchange_information_valid(self): invalid_info_1 = { "status": "BREAK", - "permissions": ["MARGIN"], + "permissionSets": [["MARGIN"]], } self.assertFalse(utils.is_exchange_information_valid(invalid_info_1)) invalid_info_2 = { "status": "BREAK", - "permissions": ["SPOT"], + "permissionSets": [["SPOT"]], } self.assertFalse(utils.is_exchange_information_valid(invalid_info_2)) invalid_info_3 = { "status": "TRADING", - "permissions": ["MARGIN"], + "permissionSets": [["MARGIN"]], } self.assertFalse(utils.is_exchange_information_valid(invalid_info_3)) invalid_info_4 = { "status": "TRADING", - "permissions": ["SPOT"], + "permissionSets": [["SPOT"]], } self.assertTrue(utils.is_exchange_information_valid(invalid_info_4)) From 50be5132e9819602b64b6668eec9a471918b9c82 Mon Sep 17 00:00:00 2001 From: mlguys Date: Thu, 25 Apr 2024 17:32:25 +0700 Subject: [PATCH 6/9] update test cases 2 --- .../sources/test_binance_rate_source.py | 64 ++++++++----------- .../core/utils/test_trading_pair_fetcher.py | 12 ++-- 2 files changed, 33 insertions(+), 43 deletions(-) diff --git a/test/hummingbot/core/rate_oracle/sources/test_binance_rate_source.py b/test/hummingbot/core/rate_oracle/sources/test_binance_rate_source.py index 091816d1b2..5a2277bf0f 100644 --- a/test/hummingbot/core/rate_oracle/sources/test_binance_rate_source.py +++ b/test/hummingbot/core/rate_oracle/sources/test_binance_rate_source.py @@ -18,10 +18,10 @@ def setUpClass(cls): cls.ev_loop = asyncio.get_event_loop() cls.target_token = "COINALPHA" cls.global_token = "HBOT" - cls.binance_pair = f"{cls.target_token}{cls.global_token}" + cls.binance_pair = f"{cls.target_token}-{cls.global_token}" cls.trading_pair = combine_to_hb_trading_pair(base=cls.target_token, quote=cls.global_token) - cls.binance_us_pair = f"{cls.target_token}USD" - cls.us_trading_pair = combine_to_hb_trading_pair(base=cls.target_token, quote="USD") + # cls.binance_us_pair = f"{cls.target_token}USD" + # cls.us_trading_pair = combine_to_hb_trading_pair(base=cls.target_token, quote="USD") cls.binance_ignored_pair = "SOMEPAIR" cls.ignored_trading_pair = combine_to_hb_trading_pair(base="SOME", quote="PAIR") @@ -30,7 +30,6 @@ def async_run_with_timeout(self, coroutine: Awaitable, timeout: int = 1): return ret def setup_binance_responses(self, mock_api, expected_rate: Decimal): - pairs_us_url = web_utils.public_rest_url(path_url=CONSTANTS.EXCHANGE_INFO_PATH_URL, domain="us") pairs_url = web_utils.public_rest_url(path_url=CONSTANTS.EXCHANGE_INFO_PATH_URL) symbols_response = { # truncated "symbols": [ @@ -39,47 +38,38 @@ def setup_binance_responses(self, mock_api, expected_rate: Decimal): "status": "TRADING", "baseAsset": self.target_token, "quoteAsset": self.global_token, - "permissions": [ + "permissionSets": [[ "SPOT", - ], - }, - { - "symbol": self.binance_us_pair, - "status": "TRADING", - "baseAsset": self.target_token, - "quoteAsset": "USD", - "permissions": [ - "SPOT", - ], + ]], }, { "symbol": self.binance_ignored_pair, "status": "PAUSED", "baseAsset": "SOME", "quoteAsset": "PAIR", - "permissions": [ + "permissionSets": [[ "SPOT", - ], + ]], }, ] } - binance_prices_us_url = web_utils.public_rest_url(path_url=CONSTANTS.TICKER_BOOK_PATH_URL, domain="us") - binance_prices_us_response = [ - { - "symbol": self.binance_us_pair, - "bidPrice": "20862.0000", - "bidQty": "0.50000000", - "askPrice": "20865.6100", - "askQty": "0.14500000", - }, - { - "symbol": self.binance_ignored_pair, - "bidPrice": "0", - "bidQty": "0", - "askPrice": "0", - "askQty": "0", - } - ] + # binance_prices_us_url = web_utils.public_rest_url(path_url=CONSTANTS.TICKER_BOOK_PATH_URL, domain="us") + # binance_prices_us_response = [ + # { + # "symbol": self.binance_us_pair, + # "bidPrice": "20862.0000", + # "bidQty": "0.50000000", + # "askPrice": "20865.6100", + # "askQty": "0.14500000", + # }, + # { + # "symbol": self.binance_ignored_pair, + # "bidPrice": "0", + # "bidQty": "0", + # "askPrice": "0", + # "askQty": "0", + # } + # ] binance_prices_global_url = web_utils.public_rest_url(path_url=CONSTANTS.TICKER_BOOK_PATH_URL) binance_prices_global_response = [ { @@ -90,9 +80,9 @@ def setup_binance_responses(self, mock_api, expected_rate: Decimal): "askQty": "0.14500000", } ] - mock_api.get(pairs_us_url, body=json.dumps(symbols_response)) + # mock_api.get(pairs_us_url, body=json.dumps(symbols_response)) mock_api.get(pairs_url, body=json.dumps(symbols_response)) - mock_api.get(binance_prices_us_url, body=json.dumps(binance_prices_us_response)) + # mock_api.get(binance_prices_us_url, body=json.dumps(binance_prices_us_response)) mock_api.get(binance_prices_global_url, body=json.dumps(binance_prices_global_response)) @aioresponses() @@ -105,5 +95,5 @@ def test_get_binance_prices(self, mock_api): self.assertIn(self.trading_pair, prices) self.assertEqual(expected_rate, prices[self.trading_pair]) - self.assertIn(self.us_trading_pair, prices) + # self.assertIn(self.us_trading_pair, prices) self.assertNotIn(self.ignored_trading_pair, prices) diff --git a/test/hummingbot/core/utils/test_trading_pair_fetcher.py b/test/hummingbot/core/utils/test_trading_pair_fetcher.py index 3436cf33e6..16253c8544 100644 --- a/test/hummingbot/core/utils/test_trading_pair_fetcher.py +++ b/test/hummingbot/core/utils/test_trading_pair_fetcher.py @@ -203,10 +203,10 @@ def test_fetch_all(self, mock_api, con_spec_mock, perp_market_mock, all_connecto "isSpotTradingAllowed": True, "isMarginTradingAllowed": True, "filters": [], - "permissions": [ + "permissionSets": [[ "SPOT", "MARGIN" - ] + ]] }, { "symbol": "LTCBTC", @@ -231,10 +231,10 @@ def test_fetch_all(self, mock_api, con_spec_mock, perp_market_mock, all_connecto "isSpotTradingAllowed": True, "isMarginTradingAllowed": True, "filters": [], - "permissions": [ + "permissionSets": [[ "SPOT", "MARGIN" - ] + ]] }, { "symbol": "BNBBTC", @@ -259,9 +259,9 @@ def test_fetch_all(self, mock_api, con_spec_mock, perp_market_mock, all_connecto "isSpotTradingAllowed": True, "isMarginTradingAllowed": True, "filters": [], - "permissions": [ + "permissionSets": [[ "MARGIN" - ] + ]] }, ] } From 1074ecd199b25f9d047a5d7c0aeef3a3b915b868 Mon Sep 17 00:00:00 2001 From: mlguys Date: Thu, 25 Apr 2024 18:10:30 +0700 Subject: [PATCH 7/9] Split binance_us rate oracle from binance --- hummingbot/client/config/client_config_map.py | 12 +++ hummingbot/core/rate_oracle/rate_oracle.py | 2 + .../sources/binance_us_rate_source.py | 87 +++++++++++++++++++ .../sources/test_binance_rate_source.py | 20 +---- .../sources/test_binance_us_rate_source.py | 84 ++++++++++++++++++ 5 files changed, 186 insertions(+), 19 deletions(-) create mode 100644 hummingbot/core/rate_oracle/sources/binance_us_rate_source.py create mode 100644 test/hummingbot/core/rate_oracle/sources/test_binance_us_rate_source.py diff --git a/hummingbot/client/config/client_config_map.py b/hummingbot/client/config/client_config_map.py index e92b90b114..d3f022efee 100644 --- a/hummingbot/client/config/client_config_map.py +++ b/hummingbot/client/config/client_config_map.py @@ -768,6 +768,17 @@ class Config: title = "binance" +class BinanceUSRateSourceMode(ExchangeRateSourceModeBase): + name: str = Field( + default="binance_us", + const=True, + client_data=None, + ) + + class Config: + title = "binance_us" + + class CubeRateSourceMode(ExchangeRateSourceModeBase): name: str = Field( default="cube", @@ -935,6 +946,7 @@ class Config: RATE_SOURCE_MODES = { AscendExRateSourceMode.Config.title: AscendExRateSourceMode, BinanceRateSourceMode.Config.title: BinanceRateSourceMode, + BinanceUSRateSourceMode.Config.title: BinanceUSRateSourceMode, CoinGeckoRateSourceMode.Config.title: CoinGeckoRateSourceMode, CoinCapRateSourceMode.Config.title: CoinCapRateSourceMode, KuCoinRateSourceMode.Config.title: KuCoinRateSourceMode, diff --git a/hummingbot/core/rate_oracle/rate_oracle.py b/hummingbot/core/rate_oracle/rate_oracle.py index 2bc58a56ca..ea8291b8cb 100644 --- a/hummingbot/core/rate_oracle/rate_oracle.py +++ b/hummingbot/core/rate_oracle/rate_oracle.py @@ -9,6 +9,7 @@ from hummingbot.core.network_iterator import NetworkStatus from hummingbot.core.rate_oracle.sources.ascend_ex_rate_source import AscendExRateSource from hummingbot.core.rate_oracle.sources.binance_rate_source import BinanceRateSource +from hummingbot.core.rate_oracle.sources.binance_us_rate_source import BinanceUSRateSource from hummingbot.core.rate_oracle.sources.coin_cap_rate_source import CoinCapRateSource from hummingbot.core.rate_oracle.sources.coin_gecko_rate_source import CoinGeckoRateSource from hummingbot.core.rate_oracle.sources.coinbase_advanced_trade_rate_source import CoinbaseAdvancedTradeRateSource @@ -22,6 +23,7 @@ RATE_ORACLE_SOURCES = { "binance": BinanceRateSource, + "binance_us": BinanceUSRateSource, "coin_gecko": CoinGeckoRateSource, "coin_cap": CoinCapRateSource, "kucoin": KucoinRateSource, diff --git a/hummingbot/core/rate_oracle/sources/binance_us_rate_source.py b/hummingbot/core/rate_oracle/sources/binance_us_rate_source.py new file mode 100644 index 0000000000..906d119854 --- /dev/null +++ b/hummingbot/core/rate_oracle/sources/binance_us_rate_source.py @@ -0,0 +1,87 @@ +from decimal import Decimal +from typing import TYPE_CHECKING, Dict, Optional + +from hummingbot.connector.utils import split_hb_trading_pair +from hummingbot.core.rate_oracle.sources.rate_source_base import RateSourceBase +from hummingbot.core.utils import async_ttl_cache +from hummingbot.core.utils.async_utils import safe_gather + +if TYPE_CHECKING: + from hummingbot.connector.exchange.binance.binance_exchange import BinanceExchange + + +class BinanceUSRateSource(RateSourceBase): + def __init__(self): + super().__init__() + self._binance_us_exchange: Optional[BinanceExchange] = None # delayed because of circular reference + + @property + def name(self) -> str: + return "binance_us" + + @async_ttl_cache(ttl=30, maxsize=1) + async def get_prices(self, quote_token: Optional[str] = None) -> Dict[str, Decimal]: + self._ensure_exchanges() + results = {} + tasks = [ + self._get_binance_prices(exchange=self._binance_us_exchange, quote_token="USD"), + ] + task_results = await safe_gather(*tasks, return_exceptions=True) + for task_result in task_results: + if isinstance(task_result, Exception): + self.logger().error( + msg="Unexpected error while retrieving rates from Binance. Check the log file for more info.", + exc_info=task_result, + ) + break + else: + results.update(task_result) + return results + + def _ensure_exchanges(self): + if self._binance_us_exchange is None: + self._binance_us_exchange = self._build_binance_connector_without_private_keys(domain="us") + + @staticmethod + async def _get_binance_prices(exchange: 'BinanceExchange', quote_token: str = None) -> Dict[str, Decimal]: + """ + Fetches binance prices + + :param exchange: The exchange instance from which to query prices. + :param quote_token: A quote symbol, if specified only pairs with the quote symbol are included for prices + :return: A dictionary of trading pairs and prices + """ + pairs_prices = await exchange.get_all_pairs_prices() + results = {} + for pair_price in pairs_prices: + try: + trading_pair = await exchange.trading_pair_associated_to_exchange_symbol(symbol=pair_price["symbol"]) + except KeyError: + continue # skip pairs that we don't track + if quote_token is not None: + base, quote = split_hb_trading_pair(trading_pair=trading_pair) + if quote != quote_token: + continue + bid_price = pair_price.get("bidPrice") + ask_price = pair_price.get("askPrice") + if bid_price is not None and ask_price is not None and 0 < Decimal(bid_price) <= Decimal(ask_price): + results[trading_pair] = (Decimal(bid_price) + Decimal(ask_price)) / Decimal("2") + + return results + + @staticmethod + def _build_binance_connector_without_private_keys(domain: str) -> 'BinanceExchange': + from hummingbot.client.hummingbot_application import HummingbotApplication + from hummingbot.connector.exchange.binance.binance_exchange import BinanceExchange + + app = HummingbotApplication.main_application() + client_config_map = app.client_config_map + + return BinanceExchange( + client_config_map=client_config_map, + binance_api_key="", + binance_api_secret="", + trading_pairs=[], + trading_required=False, + domain=domain, + ) diff --git a/test/hummingbot/core/rate_oracle/sources/test_binance_rate_source.py b/test/hummingbot/core/rate_oracle/sources/test_binance_rate_source.py index 5a2277bf0f..e864a018bf 100644 --- a/test/hummingbot/core/rate_oracle/sources/test_binance_rate_source.py +++ b/test/hummingbot/core/rate_oracle/sources/test_binance_rate_source.py @@ -20,8 +20,6 @@ def setUpClass(cls): cls.global_token = "HBOT" cls.binance_pair = f"{cls.target_token}-{cls.global_token}" cls.trading_pair = combine_to_hb_trading_pair(base=cls.target_token, quote=cls.global_token) - # cls.binance_us_pair = f"{cls.target_token}USD" - # cls.us_trading_pair = combine_to_hb_trading_pair(base=cls.target_token, quote="USD") cls.binance_ignored_pair = "SOMEPAIR" cls.ignored_trading_pair = combine_to_hb_trading_pair(base="SOME", quote="PAIR") @@ -53,23 +51,7 @@ def setup_binance_responses(self, mock_api, expected_rate: Decimal): }, ] } - # binance_prices_us_url = web_utils.public_rest_url(path_url=CONSTANTS.TICKER_BOOK_PATH_URL, domain="us") - # binance_prices_us_response = [ - # { - # "symbol": self.binance_us_pair, - # "bidPrice": "20862.0000", - # "bidQty": "0.50000000", - # "askPrice": "20865.6100", - # "askQty": "0.14500000", - # }, - # { - # "symbol": self.binance_ignored_pair, - # "bidPrice": "0", - # "bidQty": "0", - # "askPrice": "0", - # "askQty": "0", - # } - # ] + binance_prices_global_url = web_utils.public_rest_url(path_url=CONSTANTS.TICKER_BOOK_PATH_URL) binance_prices_global_response = [ { diff --git a/test/hummingbot/core/rate_oracle/sources/test_binance_us_rate_source.py b/test/hummingbot/core/rate_oracle/sources/test_binance_us_rate_source.py new file mode 100644 index 0000000000..1df451c512 --- /dev/null +++ b/test/hummingbot/core/rate_oracle/sources/test_binance_us_rate_source.py @@ -0,0 +1,84 @@ +import asyncio +import json +import unittest +from decimal import Decimal +from typing import Awaitable + +from aioresponses import aioresponses + +from hummingbot.connector.exchange.binance import binance_constants as CONSTANTS, binance_web_utils as web_utils +from hummingbot.connector.utils import combine_to_hb_trading_pair +from hummingbot.core.rate_oracle.sources.binance_us_rate_source import BinanceUSRateSource + + +class BinanceUSRateSourceTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.ev_loop = asyncio.get_event_loop() + cls.target_token = "COINALPHA" + cls.binance_us_pair = f"{cls.target_token}USD" + cls.us_trading_pair = combine_to_hb_trading_pair(base=cls.target_token, quote="USD") + cls.binance_ignored_pair = "SOMEPAIR" + cls.ignored_trading_pair = combine_to_hb_trading_pair(base="SOME", quote="PAIR") + + def async_run_with_timeout(self, coroutine: Awaitable, timeout: int = 1): + ret = asyncio.get_event_loop().run_until_complete(asyncio.wait_for(coroutine, timeout)) + return ret + + def setup_binance_responses(self, mock_api, expected_rate: Decimal): + pairs_us_url = web_utils.public_rest_url(path_url=CONSTANTS.EXCHANGE_INFO_PATH_URL, domain="us") + symbols_response = { # truncated + "symbols": [ + { + "symbol": self.binance_us_pair, + "status": "TRADING", + "baseAsset": self.target_token, + "quoteAsset": "USD", + "permissionSets": [[ + "SPOT", + ]], + }, + { + "symbol": self.binance_ignored_pair, + "status": "PAUSED", + "baseAsset": "SOME", + "quoteAsset": "PAIR", + "permissionSets": [[ + "SPOT", + ]], + }, + ] + } + binance_prices_us_url = web_utils.public_rest_url(path_url=CONSTANTS.TICKER_BOOK_PATH_URL, domain="us") + binance_prices_us_response = [ + { + "symbol": self.binance_us_pair, + "bidPrice": str(expected_rate - Decimal("0.1")), + "bidQty": "0.50000000", + "askPrice": str(expected_rate + Decimal("0.1")), + "askQty": "0.14500000", + }, + { + "symbol": self.binance_ignored_pair, + "bidPrice": "0", + "bidQty": "0", + "askPrice": "0", + "askQty": "0", + } + ] + mock_api.get(pairs_us_url, body=json.dumps(symbols_response)) + mock_api.get(binance_prices_us_url, body=json.dumps(binance_prices_us_response)) + + @aioresponses() + def test_get_binance_prices(self, mock_api): + expected_rate = Decimal("10") + self.setup_binance_responses(mock_api=mock_api, expected_rate=expected_rate) + + rate_source = BinanceUSRateSource() + prices = self.async_run_with_timeout(rate_source.get_prices()) + + self.assertIn(self.us_trading_pair, prices) + self.assertEqual(expected_rate, prices[self.us_trading_pair]) + # self.assertIn(self.us_trading_pair, prices) + self.assertNotIn(self.ignored_trading_pair, prices) From f14cb93a804425f6bb063c992cc09c00edddb6c1 Mon Sep 17 00:00:00 2001 From: mlguys Date: Thu, 25 Apr 2024 18:18:22 +0700 Subject: [PATCH 8/9] update test case name --- .../core/rate_oracle/sources/test_binance_us_rate_source.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/hummingbot/core/rate_oracle/sources/test_binance_us_rate_source.py b/test/hummingbot/core/rate_oracle/sources/test_binance_us_rate_source.py index 1df451c512..cfc1232917 100644 --- a/test/hummingbot/core/rate_oracle/sources/test_binance_us_rate_source.py +++ b/test/hummingbot/core/rate_oracle/sources/test_binance_us_rate_source.py @@ -26,7 +26,7 @@ def async_run_with_timeout(self, coroutine: Awaitable, timeout: int = 1): ret = asyncio.get_event_loop().run_until_complete(asyncio.wait_for(coroutine, timeout)) return ret - def setup_binance_responses(self, mock_api, expected_rate: Decimal): + def setup_binance_us_responses(self, mock_api, expected_rate: Decimal): pairs_us_url = web_utils.public_rest_url(path_url=CONSTANTS.EXCHANGE_INFO_PATH_URL, domain="us") symbols_response = { # truncated "symbols": [ @@ -73,12 +73,11 @@ def setup_binance_responses(self, mock_api, expected_rate: Decimal): @aioresponses() def test_get_binance_prices(self, mock_api): expected_rate = Decimal("10") - self.setup_binance_responses(mock_api=mock_api, expected_rate=expected_rate) + self.setup_binance_us_responses(mock_api=mock_api, expected_rate=expected_rate) rate_source = BinanceUSRateSource() prices = self.async_run_with_timeout(rate_source.get_prices()) self.assertIn(self.us_trading_pair, prices) self.assertEqual(expected_rate, prices[self.us_trading_pair]) - # self.assertIn(self.us_trading_pair, prices) self.assertNotIn(self.ignored_trading_pair, prices) From cce409244b174169b0bfb50cd0d6c88222a8439f Mon Sep 17 00:00:00 2001 From: mlguys Date: Thu, 25 Apr 2024 18:19:42 +0700 Subject: [PATCH 9/9] Remove binance us rate oracle from binance --- hummingbot/core/rate_oracle/sources/binance_rate_source.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/hummingbot/core/rate_oracle/sources/binance_rate_source.py b/hummingbot/core/rate_oracle/sources/binance_rate_source.py index 7dd7e13190..f3b89ea8c3 100644 --- a/hummingbot/core/rate_oracle/sources/binance_rate_source.py +++ b/hummingbot/core/rate_oracle/sources/binance_rate_source.py @@ -14,7 +14,6 @@ class BinanceRateSource(RateSourceBase): def __init__(self): super().__init__() self._binance_exchange: Optional[BinanceExchange] = None # delayed because of circular reference - # self._binance_us_exchange: Optional[BinanceExchange] = None # delayed because of circular reference @property def name(self) -> str: @@ -26,7 +25,6 @@ async def get_prices(self, quote_token: Optional[str] = None) -> Dict[str, Decim results = {} tasks = [ self._get_binance_prices(exchange=self._binance_exchange), - # self._get_binance_prices(exchange=self._binance_us_exchange, quote_token="USD"), ] task_results = await safe_gather(*tasks, return_exceptions=True) for task_result in task_results: @@ -43,7 +41,6 @@ async def get_prices(self, quote_token: Optional[str] = None) -> Dict[str, Decim def _ensure_exchanges(self): if self._binance_exchange is None: self._binance_exchange = self._build_binance_connector_without_private_keys(domain="com") - # self._binance_us_exchange = self._build_binance_connector_without_private_keys(domain="us") @staticmethod async def _get_binance_prices(exchange: 'BinanceExchange', quote_token: str = None) -> Dict[str, Decimal]: