add spot check for binance

This commit is contained in:
Stefano
2025-09-16 15:52:19 +09:00
parent 03c67d6a3b
commit 72dd0d062b

View File

@@ -3,8 +3,10 @@
import logging import logging
from datetime import UTC, datetime from datetime import UTC, datetime
from pathlib import Path from pathlib import Path
from threading import Lock
import ccxt import ccxt
from cachetools import TTLCache
from pandas import DataFrame from pandas import DataFrame
from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS
@@ -68,6 +70,11 @@ class Binance(Exchange):
(TradingMode.FUTURES, MarginMode.ISOLATED), (TradingMode.FUTURES, MarginMode.ISOLATED),
] ]
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self._spot_delist_schedule_cache: TTLCache = TTLCache(maxsize=100, ttl=300)
self._spot_delist_schedule_cache_lock = Lock()
def get_proxy_coin(self) -> str: def get_proxy_coin(self) -> str:
""" """
Get the proxy coin for the given coin Get the proxy coin for the given coin
@@ -452,11 +459,67 @@ class Binance(Exchange):
return delivery_time return delivery_time
def check_delisting_spot(self, pair: str) -> datetime | None:
return None
def check_delisting_time(self, pair: str) -> datetime | None: def check_delisting_time(self, pair: str) -> datetime | None:
if self.trading_mode == TradingMode.SPOT: if self.trading_mode == TradingMode.SPOT:
return self.check_delisting_spot(pair) return self.get_spot_pair_delist_time(pair, refresh=False)
return self.check_delisting_futures(pair) return self.check_delisting_futures(pair)
def get_spot_delist_schedule(self):
try:
delist_schedule = self._api.sapi_get_spot_delist_schedule()
return delist_schedule
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError(
f"Could not get delist schedule {e.__class__.__name__}. Message: {e}"
) from e
except ccxt.BaseError as e:
raise OperationalException(e) from e
def get_spot_pair_delist_time(self, pair: str, refresh: bool = True) -> datetime | None:
"""
Get the delisting time for a pair if it will be delisted
:param pair: Pair to get the delisting time for
:param refresh: true if you need fresh data
:return: int: delisting time None if not delisting
"""
if not pair:
return None
cache = self._spot_delist_schedule_cache
lock = self._spot_delist_schedule_cache_lock
if not refresh:
with lock:
delist_time = cache.get(pair, None)
if delist_time:
return delist_time
delist_schedule = self.get_spot_delist_schedule()
if delist_schedule is None:
return None
with lock:
for schedule in delist_schedule:
delist_dt = dt_from_ts(int(schedule["delistTime"]))
for symbol in schedule["symbols"]:
ft_symbol = next(
(
pair
for pair, market in self.markets.items()
if market.get("id", None) == symbol
),
None,
)
if ft_symbol is None:
continue
cache[ft_symbol] = delist_dt
logger.info(f"{ft_symbol} delisted at {delist_dt}")
return cache.get(pair, None)