diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 2ea2eec2b..2974adb0a 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -439,7 +439,7 @@ class Binance(Exchange): pair, until=until, since=since, from_id=from_id ) - def check_delisting_futures(self, pair: str) -> datetime | None: + def _check_delisting_futures(self, pair: str) -> datetime | None: delivery_time = self.markets.get(pair, {}).get("info", {}).get("deliveryDate", None) if delivery_time: if isinstance(delivery_time, str) and (delivery_time != ""): @@ -459,14 +459,20 @@ class Binance(Exchange): return delivery_time def check_delisting_time(self, pair: str) -> datetime | None: + """ + Check if the pair gonna be delisted. + By default, it returns None. + :param pair: Market symbol + :return: Datetime if the pair gonna be delisted, None otherwise + """ if self._config["runmode"] not in TRADE_MODES: return None if self.trading_mode == TradingMode.FUTURES: - return self.check_delisting_futures(pair) - return self.get_spot_pair_delist_time(pair, refresh=False) + return self._check_delisting_futures(pair) + return self._get_spot_pair_delist_time(pair, refresh=False) - def get_spot_delist_schedule(self): + def _get_spot_delist_schedule(self): """ Get the delisting schedule for spot pairs Only works in live mode as it requires API keys, @@ -494,7 +500,7 @@ class Binance(Exchange): except ccxt.BaseError as e: raise OperationalException(e) from e - def get_spot_pair_delist_time(self, pair: str, refresh: bool = False) -> datetime | None: + def _get_spot_pair_delist_time(self, pair: str, refresh: bool = False) -> datetime | None: """ Get the delisting time for a pair if it will be delisted :param pair: Pair to get the delisting time for @@ -512,7 +518,7 @@ class Binance(Exchange): if delist_time := cache.get(pair, None): return delist_time - delist_schedule = self.get_spot_delist_schedule() + delist_schedule = self._get_spot_delist_schedule() if delist_schedule is None: return None diff --git a/tests/exchange/test_binance.py b/tests/exchange/test_binance.py index 295da72bc..2c11fc2f3 100644 --- a/tests/exchange/test_binance.py +++ b/tests/exchange/test_binance.py @@ -1116,8 +1116,8 @@ def test_check_delisting_time_binance(default_conf_usdt, mocker): exchange._config["runmode"] = RunMode.BACKTEST delist_mock = MagicMock(return_value=None) delist_fut_mock = MagicMock(return_value=None) - mocker.patch.object(exchange, "get_spot_pair_delist_time", delist_mock) - mocker.patch.object(exchange, "check_delisting_futures", delist_fut_mock) + mocker.patch.object(exchange, "_get_spot_pair_delist_time", delist_mock) + mocker.patch.object(exchange, "_check_delisting_futures", delist_fut_mock) # Invalid run mode resp = exchange.check_delisting_time("BTC/USDT") @@ -1141,7 +1141,7 @@ def test_check_delisting_time_binance(default_conf_usdt, mocker): assert delist_fut_mock.call_count == 1 -def test_check_delisting_futures_binance(default_conf_usdt, mocker, markets): +def test__check_delisting_futures_binance(default_conf_usdt, mocker, markets): markets["BTC/USDT:USDT"] = deepcopy(markets["SOL/BUSD:BUSD"]) markets["BTC/USDT:USDT"]["info"]["deliveryDate"] = 4133404800000 markets["SOL/BUSD:BUSD"]["info"]["deliveryDate"] = 4133404800000 @@ -1149,33 +1149,35 @@ def test_check_delisting_futures_binance(default_conf_usdt, mocker, markets): exchange = get_patched_exchange(mocker, default_conf_usdt, exchange="binance") mocker.patch(f"{EXMS}.markets", PropertyMock(return_value=markets)) - resp_sol = exchange.check_delisting_futures("SOL/BUSD:BUSD") + resp_sol = exchange._check_delisting_futures("SOL/BUSD:BUSD") # Delisting is equal to BTC assert resp_sol is None # Actually has a delisting date - resp_ada = exchange.check_delisting_futures("ADA/USDT:USDT") + resp_ada = exchange._check_delisting_futures("ADA/USDT:USDT") assert resp_ada == dt_utc(2025, 10, 18) -def test_get_spot_delist_schedule_binance(default_conf_usdt, mocker): +def test__get_spot_delist_schedule_binance(default_conf_usdt, mocker): exchange = get_patched_exchange(mocker, default_conf_usdt, exchange="binance") ret_value = [{"delistTime": 1759114800000, "symbols": ["ETCBTC"]}] - schedule_mock = mocker.patch.object(exchange, "get_spot_delist_schedule", return_value=None) + schedule_mock = mocker.patch.object(exchange, "_get_spot_delist_schedule", return_value=None) # None - mode is DRY - assert exchange.get_spot_pair_delist_time("ETC/BTC") is None + assert exchange._get_spot_pair_delist_time("ETC/BTC") is None # Switch to live exchange._config["runmode"] = RunMode.LIVE - assert exchange.get_spot_pair_delist_time("ETC/BTC") is None + assert exchange._get_spot_pair_delist_time("ETC/BTC") is None - mocker.patch.object(exchange, "get_spot_delist_schedule", return_value=ret_value) - resp = exchange.get_spot_pair_delist_time("ETC/BTC") + mocker.patch.object(exchange, "_get_spot_delist_schedule", return_value=ret_value) + resp = exchange._get_spot_pair_delist_time("ETC/BTC") assert resp == dt_utc(2025, 9, 29, 3, 0) assert schedule_mock.call_count == 1 schedule_mock.reset_mock() # Caching - don't refresh. - assert exchange.get_spot_pair_delist_time("ETC/BTC", refresh=False) == dt_utc(2025, 9, 29, 3, 0) + assert exchange._get_spot_pair_delist_time("ETC/BTC", refresh=False) == dt_utc( + 2025, 9, 29, 3, 0 + ) assert schedule_mock.call_count == 0 api_mock = MagicMock() @@ -1184,7 +1186,7 @@ def test_get_spot_delist_schedule_binance(default_conf_usdt, mocker): default_conf_usdt, api_mock, "binance", - "get_spot_delist_schedule", + "_get_spot_delist_schedule", "sapi_get_spot_delist_schedule", retries=1, )