mirror of
https://github.com/freqtrade/freqtrade.git
synced 2024-11-10 02:12:01 +00:00
Compare commits
10 Commits
954da3298f
...
bf088f3d4d
Author | SHA1 | Date | |
---|---|---|---|
|
bf088f3d4d | ||
|
5ec04d168e | ||
|
26afad8bc1 | ||
|
80dd586dc7 | ||
|
78d189564f | ||
|
2b0b85330e | ||
|
4257e1ca96 | ||
|
ff2eaeb3b4 | ||
|
cbc98d384e | ||
|
4ef45314dd |
|
@ -6,6 +6,8 @@ from pathlib import Path
|
|||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
import ccxt
|
||||
from cachetools import TTLCache, cached
|
||||
from threading import Lock
|
||||
|
||||
from freqtrade.enums import CandleType, MarginMode, PriceType, TradingMode
|
||||
from freqtrade.exceptions import DDosProtection, OperationalException, TemporaryError
|
||||
|
@ -53,6 +55,11 @@ class Binance(Exchange):
|
|||
(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_tickers(self, symbols: Optional[List[str]] = None, cached: bool = False) -> Tickers:
|
||||
tickers = super().get_tickers(symbols=symbols, cached=cached)
|
||||
if self.trading_mode == TradingMode.FUTURES:
|
||||
|
@ -214,3 +221,58 @@ class Binance(Exchange):
|
|||
return self.get_leverage_tiers()
|
||||
else:
|
||||
return {}
|
||||
|
||||
|
||||
|
||||
@retrier
|
||||
@cached(cache=TTLCache(maxsize=100, ttl=10), lock=Lock())
|
||||
def get_deslist_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, refresh: bool = True) -> int | 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
|
||||
|
||||
cache = self._spot_delist_schedule_cache
|
||||
lock = self._spot_delist_schedule_cache_lock
|
||||
|
||||
schedule_pair = pair.replace('/', '')
|
||||
|
||||
if not refresh:
|
||||
with lock:
|
||||
delist_time = cache[f"{schedule_pair}"]
|
||||
|
||||
if delist_time:
|
||||
return delist_time
|
||||
|
||||
delist_schedule = self.get_deslist_schedule()
|
||||
|
||||
if delist_schedule is None:
|
||||
return None
|
||||
|
||||
with lock:
|
||||
for schedule in delist_schedule:
|
||||
for symbol in schedule['symbols']:
|
||||
cache[f"{symbol}"] = int(schedule['delistTime'])
|
||||
|
||||
|
||||
with lock:
|
||||
return cache.get(f"{schedule_pair}")
|
||||
|
|
|
@ -723,3 +723,16 @@ def test_get_maintenance_ratio_and_amt_binance(
|
|||
exchange._leverage_tiers = leverage_tiers
|
||||
(result_ratio, result_amt) = exchange.get_maintenance_ratio_and_amt(pair, notional_value)
|
||||
assert (round(result_ratio, 8), round(result_amt, 8)) == (mm_ratio, amt)
|
||||
|
||||
|
||||
def test_get_spot_delist_schedule(mocker, default_conf) -> None:
|
||||
exchange = get_patched_exchange(mocker, default_conf, id='binance')
|
||||
return_value = [{
|
||||
'delistTime': '1712113200000',
|
||||
'symbols': ['DREPBTC', 'DREPUSDT', 'MOBBTC', 'MOBUSDT', 'PNTUSDT']
|
||||
}]
|
||||
|
||||
exchange._api.sapi_get_spot_delist_schedule = MagicMock(return_value=return_value)
|
||||
|
||||
assert exchange.get_spot_pair_delist_time('DREP/USDT') == 1712113200000
|
||||
assert exchange.get_spot_pair_delist_time('BTC/USDT') is None
|
||||
|
|
Loading…
Reference in New Issue
Block a user