Add support for fudging unavailable funding rates, allowing backtesting of timeranges where futures candles are available, but rates are not
This commit is contained in:
parent
7b9439f2e4
commit
bb758da940
@ -230,6 +230,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi
|
|||||||
| `dataformat_trades` | Data format to use to store historical trades data. <br> *Defaults to `jsongz`*. <br> **Datatype:** String
|
| `dataformat_trades` | Data format to use to store historical trades data. <br> *Defaults to `jsongz`*. <br> **Datatype:** String
|
||||||
| `position_adjustment_enable` | Enables the strategy to use position adjustments (additional buys or sells). [More information here](strategy-callbacks.md#adjust-trade-position). <br> [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.*<br> **Datatype:** Boolean
|
| `position_adjustment_enable` | Enables the strategy to use position adjustments (additional buys or sells). [More information here](strategy-callbacks.md#adjust-trade-position). <br> [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.*<br> **Datatype:** Boolean
|
||||||
| `max_entry_position_adjustment` | Maximum additional order(s) for each open trade on top of the first entry Order. Set it to `-1` for unlimited additional orders. [More information here](strategy-callbacks.md#adjust-trade-position). <br> [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `-1`.*<br> **Datatype:** Positive Integer or -1
|
| `max_entry_position_adjustment` | Maximum additional order(s) for each open trade on top of the first entry Order. Set it to `-1` for unlimited additional orders. [More information here](strategy-callbacks.md#adjust-trade-position). <br> [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `-1`.*<br> **Datatype:** Positive Integer or -1
|
||||||
|
| `futures_funding_rate` | User-specified funding rate to be used when historical funding rates are not available from the exchange. This does not overwrite real historical rates. It is recommended that this be set to 0 unless you are testing a specific coin and you understand how the funding rate will affect freqtrade's profit calculations. [More information here](configuration.md) <br>*Defaults to None.*<br> **Datatype:** Float
|
||||||
|
|
||||||
### Parameters in the strategy
|
### Parameters in the strategy
|
||||||
|
|
||||||
|
@ -101,6 +101,12 @@ Possible values are any floats between 0.0 and 0.99
|
|||||||
!!! Danger "A `liquidation_buffer` of 0.0, or a low `liquidation_buffer` is likely to result in liquidations, and liquidation fees"
|
!!! Danger "A `liquidation_buffer` of 0.0, or a low `liquidation_buffer` is likely to result in liquidations, and liquidation fees"
|
||||||
Currently Freqtrade is able to calculate liquidation prices, but does not calculate liquidation fees. Setting your `liquidation_buffer` to 0.0, or using a low `liquidation_buffer` could result in your positions being liquidated. Freqtrade does not track liquidation fees, so liquidations will result in inaccurate profit/loss results for your bot. If you use a low `liquidation_buffer`, it is recommended to use `stoploss_on_exchange` if your exchange supports this.
|
Currently Freqtrade is able to calculate liquidation prices, but does not calculate liquidation fees. Setting your `liquidation_buffer` to 0.0, or using a low `liquidation_buffer` could result in your positions being liquidated. Freqtrade does not track liquidation fees, so liquidations will result in inaccurate profit/loss results for your bot. If you use a low `liquidation_buffer`, it is recommended to use `stoploss_on_exchange` if your exchange supports this.
|
||||||
|
|
||||||
|
## Unavailable funding rates
|
||||||
|
|
||||||
|
For futures data, exchanges commonly provide the futures candles, the marks, and the funding rates. However, it is common that whilst candles and marks might be available, the funding rates are not. This can affect backtesting timeranges, i.e. you may only be able to test recent timeranges and not earlier, experiencing the `No data found. Terminating.` error. To get around this, add the `futures_funding_rate` config option as listed in [configuration.md](configuration.md), and it is recommended that you set this to `0`, unless you know a given specific funding rate for your pair, exchange and timerange. Setting this to anything other than `0` can have drastic effects on your profit calculations within strategy, e.g. within the `custom_exit`, `custom_stoploss`, etc functions.
|
||||||
|
|
||||||
|
!!! This will not overwrite funding rates that are available from the exchange.
|
||||||
|
|
||||||
### Developer
|
### Developer
|
||||||
|
|
||||||
#### Margin mode
|
#### Margin mode
|
||||||
|
@ -68,7 +68,8 @@ def load_data(datadir: Path,
|
|||||||
startup_candles: int = 0,
|
startup_candles: int = 0,
|
||||||
fail_without_data: bool = False,
|
fail_without_data: bool = False,
|
||||||
data_format: str = 'json',
|
data_format: str = 'json',
|
||||||
candle_type: CandleType = CandleType.SPOT
|
candle_type: CandleType = CandleType.SPOT,
|
||||||
|
user_futures_funding_rate = None,
|
||||||
) -> Dict[str, DataFrame]:
|
) -> Dict[str, DataFrame]:
|
||||||
"""
|
"""
|
||||||
Load ohlcv history data for a list of pairs.
|
Load ohlcv history data for a list of pairs.
|
||||||
@ -100,6 +101,10 @@ def load_data(datadir: Path,
|
|||||||
)
|
)
|
||||||
if not hist.empty:
|
if not hist.empty:
|
||||||
result[pair] = hist
|
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:
|
if fail_without_data and not result:
|
||||||
raise OperationalException("No data found. Terminating.")
|
raise OperationalException("No data found. Terminating.")
|
||||||
|
@ -275,8 +275,27 @@ class Backtesting:
|
|||||||
if pair not in self.exchange._leverage_tiers:
|
if pair not in self.exchange._leverage_tiers:
|
||||||
unavailable_pairs.append(pair)
|
unavailable_pairs.append(pair)
|
||||||
continue
|
continue
|
||||||
self.futures_data[pair] = funding_rates_dict[pair].merge(
|
|
||||||
mark_rates_dict[pair], on='date', how="inner", suffixes=["_fund", "_mark"])
|
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]["close_fund"] = 0.0
|
||||||
|
mark_rates_dict[pair]["high_fund"] = 0.0
|
||||||
|
mark_rates_dict[pair]["low_fund"] = 0.0
|
||||||
|
mark_rates_dict[pair]["volume_fund"] = 0.0
|
||||||
|
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:
|
||||||
|
self.futures_data[pair] = mark_rates_dict[pair].merge(
|
||||||
|
funding_rates_dict[pair], on='date', how="inner", suffixes=["_fund", "_mark"])
|
||||||
|
|
||||||
if unavailable_pairs:
|
if unavailable_pairs:
|
||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
|
Loading…
Reference in New Issue
Block a user