diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 65d9909c6..9372c77b7 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -2413,14 +2413,33 @@ class Exchange: ) @staticmethod - def combine_funding_and_mark(funding_rates: DataFrame, mark_rates: DataFrame) -> DataFrame: + def combine_funding_and_mark(funding_rates: DataFrame, mark_rates: DataFrame, + futures_funding_rate: Optional[int] = None) -> DataFrame: """ Combine funding-rates and mark-rates dataframes :param funding_rates: Dataframe containing Funding rates (Type FUNDING_RATE) :param mark_rates: Dataframe containing Mark rates (Type mark_ohlcv_price) + :param futures_funding_rate: Fake funding rate to use if funding_rates are not available """ + if futures_funding_rate is None: + return mark_rates.merge( + funding_rates, on='date', how="inner", suffixes=["_mark", "_fund"]) + else: + if len(funding_rates) == 0: + # No funding rate candles - full fillup with fallback variable + mark_rates['open_fund'] = futures_funding_rate + return mark_rates.rename( + columns={'open': 'open_mark', + 'close': 'close_mark', + 'high': 'high_mark', + 'low': 'low_mark', + 'volume': 'volume_mark'}) - return mark_rates.merge(funding_rates, on='date', how="inner", suffixes=["_mark", "_fund"]) + else: + # Fill up missing funding_rate candles with fallback value + return mark_rates.merge( + funding_rates, on='date', how="outer", suffixes=["_mark", "_fund"] + )['open_fund'].fillna(futures_funding_rate) def calculate_funding_fees( self, diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 3041136a3..2c34e29b0 100755 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -276,30 +276,11 @@ class Backtesting: unavailable_pairs.append(pair) continue - if (pair in mark_rates_dict - and len(funding_rates_dict[pair]) == 0 - and "futures_funding_rate" in self.config): - mark_rates_dict[pair]["open_fund"] = self.config.get('futures_funding_rate') - mark_rates_dict[pair].rename( - columns={'open': 'open_mark', - 'close': 'close_mark', - 'high': 'high_mark', - 'low': 'low_mark', - 'volume': 'volume_mark'}, - inplace=True) - - self.futures_data[pair] = mark_rates_dict[pair] - else: - if "futures_funding_rate" in self.config: - self.futures_data[pair] = mark_rates_dict[pair].merge( - funding_rates_dict[pair], on='date', - how="outer", suffixes=["_mark", "_fund"])['open_fund'].fillna( - self.config.get('futures_funding_rate')) - else: - self.futures_data[pair] = self.exchange.combine_funding_and_mark( - funding_rates=funding_rates_dict[pair], - mark_rates=mark_rates_dict[pair] - ) + self.futures_data[pair] = self.exchange.combine_funding_and_mark( + funding_rates=funding_rates_dict[pair], + mark_rates=mark_rates_dict[pair], + futures_funding_rate=self.config.get('futures_funding_rate'), + ) if unavailable_pairs: raise OperationalException(