Merge pull request #6857 from froggleston/develop

Add support for fudging unavailable funding rates, allowing backtesti…
This commit is contained in:
Matthias
2022-05-23 06:31:51 +02:00
committed by GitHub
6 changed files with 107 additions and 5 deletions

View File

@@ -68,7 +68,8 @@ def load_data(datadir: Path,
startup_candles: int = 0,
fail_without_data: bool = False,
data_format: str = 'json',
candle_type: CandleType = CandleType.SPOT
candle_type: CandleType = CandleType.SPOT,
user_futures_funding_rate: int = None,
) -> Dict[str, DataFrame]:
"""
Load ohlcv history data for a list of pairs.
@@ -100,6 +101,10 @@ def load_data(datadir: Path,
)
if not hist.empty:
result[pair] = hist
else:
if candle_type is CandleType.FUNDING_RATE and user_futures_funding_rate is not None:
logger.warn(f"{pair} using user specified [{user_futures_funding_rate}]")
result[pair] = DataFrame(columns=["open", "close", "high", "low", "volume"])
if fail_without_data and not result:
raise OperationalException("No data found. Terminating.")

View File

@@ -2419,14 +2419,35 @@ 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 funding_rates.merge(mark_rates, on='date', how="inner", suffixes=["_fund", "_mark"])
else:
# Fill up missing funding_rate candles with fallback value
combined = mark_rates.merge(
funding_rates, on='date', how="outer", suffixes=["_mark", "_fund"]
)
combined['open_fund'] = combined['open_fund'].fillna(futures_funding_rate)
return combined
def calculate_funding_fees(
self,

View File

@@ -275,8 +275,12 @@ class Backtesting:
if pair not in self.exchange._leverage_tiers:
unavailable_pairs.append(pair)
continue
self.futures_data[pair] = funding_rates_dict[pair].merge(
mark_rates_dict[pair], on='date', how="inner", suffixes=["_fund", "_mark"])
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', None),
)
if unavailable_pairs:
raise OperationalException(