mirror of
https://github.com/freqtrade/freqtrade.git
synced 2025-12-15 04:11:14 +00:00
switch to use dataprovider to give flexibility to users
This commit is contained in:
@@ -604,3 +604,19 @@ class DataProvider:
|
|||||||
if always_send or message not in self.__msg_cache:
|
if always_send or message not in self.__msg_cache:
|
||||||
self._msg_queue.append(message)
|
self._msg_queue.append(message)
|
||||||
self.__msg_cache[message] = True
|
self.__msg_cache[message] = True
|
||||||
|
|
||||||
|
def check_delisting(self, pair: str) -> datetime | None:
|
||||||
|
"""
|
||||||
|
Check if a pair gonna be delisted on the exchange.
|
||||||
|
Will only return datetime if the pair is gonna be delisted.
|
||||||
|
:param pair: Pair to check
|
||||||
|
:return: Datetime of the pair's delisting, None otherwise
|
||||||
|
"""
|
||||||
|
if self._exchange is None:
|
||||||
|
raise OperationalException(NO_EXCHANGE_EXCEPTION)
|
||||||
|
|
||||||
|
try:
|
||||||
|
return self._exchange.check_delisting_time(pair)
|
||||||
|
except ExchangeError:
|
||||||
|
logger.warning(f"Could not fetch market data for {pair}. Assuming no delisting.")
|
||||||
|
return None
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ class Binance(Exchange):
|
|||||||
"BNFCR": "USDC",
|
"BNFCR": "USDC",
|
||||||
"BFUSD": "USDT",
|
"BFUSD": "USDT",
|
||||||
},
|
},
|
||||||
"delivery_column": "deliveryDate",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
|
_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
|
||||||
@@ -433,3 +432,31 @@ class Binance(Exchange):
|
|||||||
return await super()._async_get_trade_history_id(
|
return await super()._async_get_trade_history_id(
|
||||||
pair, until=until, since=since, from_id=from_id
|
pair, until=until, since=since, from_id=from_id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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 != ""):
|
||||||
|
delivery_time = int(delivery_time)
|
||||||
|
|
||||||
|
# Binance set a very high delivery time for all perpetuals.
|
||||||
|
# We compare with delivery time of BTC/USDT:USDT which assumed to never be delisted
|
||||||
|
btc_delivery_time = (
|
||||||
|
self.markets.get("BTC/USDT:USDT", {}).get("info", {}).get("deliveryDate", None)
|
||||||
|
)
|
||||||
|
|
||||||
|
if delivery_time == btc_delivery_time:
|
||||||
|
return None
|
||||||
|
|
||||||
|
delivery_time = dt_from_ts(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:
|
||||||
|
if self.trading_mode == TradingMode.SPOT:
|
||||||
|
return self.check_delisting_spot(pair)
|
||||||
|
|
||||||
|
return self.check_delisting_futures(pair)
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ class Bybit(Exchange):
|
|||||||
"exchange_has_overrides": {
|
"exchange_has_overrides": {
|
||||||
"fetchOrder": True,
|
"fetchOrder": True,
|
||||||
},
|
},
|
||||||
"delivery_column": "deliveryTime",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
|
_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
|
||||||
|
|||||||
@@ -3912,31 +3912,13 @@ class Exchange:
|
|||||||
else:
|
else:
|
||||||
raise ExchangeError(f"Cannot get maintenance ratio using {self.name}")
|
raise ExchangeError(f"Cannot get maintenance ratio using {self.name}")
|
||||||
|
|
||||||
def check_delivery_time(self, pair: str) -> int:
|
def check_delisting_time(self, pair: str) -> datetime | None:
|
||||||
"""
|
"""
|
||||||
Check if the futures contract is a delivery contract
|
Check if the pair gonna be delisted.
|
||||||
|
This function should be overridden by the exchange class if the exchange
|
||||||
|
provides such information.
|
||||||
|
By default, it returns None.
|
||||||
:param pair: Market symbol
|
:param pair: Market symbol
|
||||||
:return: True if the contract is a delivery contract, False otherwise
|
:return: Datetime if the pair gonna be delisted, None otherwise
|
||||||
"""
|
"""
|
||||||
if self.trading_mode != TradingMode.FUTURES:
|
return None
|
||||||
return 0
|
|
||||||
|
|
||||||
column_to_check = self._ft_has.get("delivery_column", "")
|
|
||||||
|
|
||||||
delivery_time = self.markets.get(pair, {}).get("info", {}).get(column_to_check, None)
|
|
||||||
if delivery_time:
|
|
||||||
if isinstance(delivery_time, str) and (delivery_time != ""):
|
|
||||||
delivery_time = int(delivery_time)
|
|
||||||
|
|
||||||
if self.name == "Binance":
|
|
||||||
# Binance set a very high delivery time for all perpetuals.
|
|
||||||
# We compare with delivery time of BTC/USDT:USDT which assumed to never be delisted
|
|
||||||
btc_delivery_time = (
|
|
||||||
self.markets.get("BTC/USDT:USDT", {}).get("info", {}).get(column_to_check, None)
|
|
||||||
)
|
|
||||||
|
|
||||||
if delivery_time == btc_delivery_time:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
return delivery_time
|
|
||||||
return 0
|
|
||||||
|
|||||||
@@ -63,9 +63,6 @@ class FtHas(TypedDict, total=False):
|
|||||||
# Websocket control
|
# Websocket control
|
||||||
ws_enabled: bool
|
ws_enabled: bool
|
||||||
|
|
||||||
# Delisting checks
|
|
||||||
delivery_column: str
|
|
||||||
|
|
||||||
|
|
||||||
class Ticker(TypedDict):
|
class Ticker(TypedDict):
|
||||||
symbol: str
|
symbol: str
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ class Okx(Exchange):
|
|||||||
},
|
},
|
||||||
"stoploss_blocks_assets": False,
|
"stoploss_blocks_assets": False,
|
||||||
"ws_enabled": True,
|
"ws_enabled": True,
|
||||||
"delivery_column": "expTime",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
|
_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
|
||||||
|
|||||||
@@ -661,19 +661,6 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
"""
|
"""
|
||||||
logger.debug(f"create_trade for pair {pair}")
|
logger.debug(f"create_trade for pair {pair}")
|
||||||
|
|
||||||
delivery_time = self.exchange.check_delivery_time(pair)
|
|
||||||
if delivery_time:
|
|
||||||
delivery_date = dt_from_ts(delivery_time)
|
|
||||||
logger.info(
|
|
||||||
f"Pair {pair} has a delivery time of "
|
|
||||||
f"{delivery_date.strftime(constants.DATETIME_PRINT_FORMAT)}."
|
|
||||||
)
|
|
||||||
|
|
||||||
if pair not in self.pairlists.blacklist:
|
|
||||||
self.pairlists.blacklist.append(pair)
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
analyzed_df, _ = self.dataprovider.get_analyzed_dataframe(pair, self.strategy.timeframe)
|
analyzed_df, _ = self.dataprovider.get_analyzed_dataframe(pair, self.strategy.timeframe)
|
||||||
nowtime = analyzed_df.iloc[-1]["date"] if len(analyzed_df) > 0 else None
|
nowtime = analyzed_df.iloc[-1]["date"] if len(analyzed_df) > 0 else None
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user