Fix unreliable backtest-result when using webserver mode
This commit is contained in:
parent
4c268847d4
commit
6319c104fe
@ -149,6 +149,8 @@ class DataProvider:
|
|||||||
Clear pair dataframe cache.
|
Clear pair dataframe cache.
|
||||||
"""
|
"""
|
||||||
self.__cached_pairs = {}
|
self.__cached_pairs = {}
|
||||||
|
self.__cached_pairs_backtesting = {}
|
||||||
|
self.__slice_index = 0
|
||||||
|
|
||||||
# Exchange functions
|
# Exchange functions
|
||||||
|
|
||||||
|
@ -85,18 +85,7 @@ class Backtesting:
|
|||||||
"configuration or as cli argument `--timeframe 5m`")
|
"configuration or as cli argument `--timeframe 5m`")
|
||||||
self.timeframe = str(self.config.get('timeframe'))
|
self.timeframe = str(self.config.get('timeframe'))
|
||||||
self.timeframe_min = timeframe_to_minutes(self.timeframe)
|
self.timeframe_min = timeframe_to_minutes(self.timeframe)
|
||||||
# Load detail timeframe if specified
|
self.init_backtest_detail()
|
||||||
self.timeframe_detail = str(self.config.get('timeframe_detail', ''))
|
|
||||||
if self.timeframe_detail:
|
|
||||||
self.timeframe_detail_min = timeframe_to_minutes(self.timeframe_detail)
|
|
||||||
if self.timeframe_min <= self.timeframe_detail_min:
|
|
||||||
raise OperationalException(
|
|
||||||
"Detail timeframe must be smaller than strategy timeframe.")
|
|
||||||
|
|
||||||
else:
|
|
||||||
self.timeframe_detail_min = 0
|
|
||||||
self.detail_data: Dict[str, DataFrame] = {}
|
|
||||||
|
|
||||||
self.pairlists = PairListManager(self.exchange, self.config)
|
self.pairlists = PairListManager(self.exchange, self.config)
|
||||||
if 'VolumePairList' in self.pairlists.name_list:
|
if 'VolumePairList' in self.pairlists.name_list:
|
||||||
raise OperationalException("VolumePairList not allowed for backtesting.")
|
raise OperationalException("VolumePairList not allowed for backtesting.")
|
||||||
@ -119,14 +108,6 @@ class Backtesting:
|
|||||||
else:
|
else:
|
||||||
self.fee = self.exchange.get_fee(symbol=self.pairlists.whitelist[0])
|
self.fee = self.exchange.get_fee(symbol=self.pairlists.whitelist[0])
|
||||||
|
|
||||||
Trade.use_db = False
|
|
||||||
Trade.reset_trades()
|
|
||||||
PairLocks.timeframe = self.config['timeframe']
|
|
||||||
PairLocks.use_db = False
|
|
||||||
PairLocks.reset_locks()
|
|
||||||
|
|
||||||
self.wallets = Wallets(self.config, self.exchange, log=False)
|
|
||||||
|
|
||||||
self.timerange = TimeRange.parse_timerange(
|
self.timerange = TimeRange.parse_timerange(
|
||||||
None if self.config.get('timerange') is None else str(self.config.get('timerange')))
|
None if self.config.get('timerange') is None else str(self.config.get('timerange')))
|
||||||
|
|
||||||
@ -135,9 +116,7 @@ class Backtesting:
|
|||||||
# Add maximum startup candle count to configuration for informative pairs support
|
# Add maximum startup candle count to configuration for informative pairs support
|
||||||
self.config['startup_candle_count'] = self.required_startup
|
self.config['startup_candle_count'] = self.required_startup
|
||||||
self.exchange.validate_required_startup_candles(self.required_startup, self.timeframe)
|
self.exchange.validate_required_startup_candles(self.required_startup, self.timeframe)
|
||||||
|
self.init_backtest()
|
||||||
self.progress = BTProgress()
|
|
||||||
self.abort = False
|
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
self.cleanup()
|
self.cleanup()
|
||||||
@ -147,6 +126,28 @@ class Backtesting:
|
|||||||
PairLocks.use_db = True
|
PairLocks.use_db = True
|
||||||
Trade.use_db = True
|
Trade.use_db = True
|
||||||
|
|
||||||
|
def init_backtest_detail(self):
|
||||||
|
# Load detail timeframe if specified
|
||||||
|
self.timeframe_detail = str(self.config.get('timeframe_detail', ''))
|
||||||
|
if self.timeframe_detail:
|
||||||
|
self.timeframe_detail_min = timeframe_to_minutes(self.timeframe_detail)
|
||||||
|
if self.timeframe_min <= self.timeframe_detail_min:
|
||||||
|
raise OperationalException(
|
||||||
|
"Detail timeframe must be smaller than strategy timeframe.")
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.timeframe_detail_min = 0
|
||||||
|
self.detail_data: Dict[str, DataFrame] = {}
|
||||||
|
|
||||||
|
def init_backtest(self):
|
||||||
|
|
||||||
|
self.prepare_backtest(False)
|
||||||
|
|
||||||
|
self.wallets = Wallets(self.config, self.exchange, log=False)
|
||||||
|
|
||||||
|
self.progress = BTProgress()
|
||||||
|
self.abort = False
|
||||||
|
|
||||||
def _set_strategy(self, strategy: IStrategy):
|
def _set_strategy(self, strategy: IStrategy):
|
||||||
"""
|
"""
|
||||||
Load strategy into backtesting
|
Load strategy into backtesting
|
||||||
@ -226,7 +227,8 @@ class Backtesting:
|
|||||||
Trade.reset_trades()
|
Trade.reset_trades()
|
||||||
self.rejected_trades = 0
|
self.rejected_trades = 0
|
||||||
self.dataprovider.clear_cache()
|
self.dataprovider.clear_cache()
|
||||||
self._load_protections(self.strategy)
|
if enable_protections:
|
||||||
|
self._load_protections(self.strategy)
|
||||||
|
|
||||||
def check_abort(self):
|
def check_abort(self):
|
||||||
"""
|
"""
|
||||||
|
@ -47,33 +47,34 @@ async def api_start_backtest(bt_settings: BacktestRequest, background_tasks: Bac
|
|||||||
not ApiServer._bt
|
not ApiServer._bt
|
||||||
or lastconfig.get('timeframe') != strat.timeframe
|
or lastconfig.get('timeframe') != strat.timeframe
|
||||||
or lastconfig.get('timeframe_detail') != btconfig.get('timeframe_detail')
|
or lastconfig.get('timeframe_detail') != btconfig.get('timeframe_detail')
|
||||||
or lastconfig.get('dry_run_wallet') != btconfig.get('dry_run_wallet', 0)
|
|
||||||
or lastconfig.get('timerange') != btconfig['timerange']
|
or lastconfig.get('timerange') != btconfig['timerange']
|
||||||
):
|
):
|
||||||
from freqtrade.optimize.backtesting import Backtesting
|
from freqtrade.optimize.backtesting import Backtesting
|
||||||
ApiServer._bt = Backtesting(btconfig)
|
ApiServer._bt = Backtesting(btconfig)
|
||||||
if ApiServer._bt.timeframe_detail:
|
if ApiServer._bt.timeframe_detail:
|
||||||
ApiServer._bt.load_bt_data_detail()
|
ApiServer._bt.load_bt_data_detail()
|
||||||
|
else:
|
||||||
|
ApiServer._bt.config = btconfig
|
||||||
|
ApiServer._bt.init_backtest()
|
||||||
# Only reload data if timeframe changed.
|
# Only reload data if timeframe changed.
|
||||||
if (
|
if (
|
||||||
not ApiServer._bt_data
|
not ApiServer._bt_data
|
||||||
or not ApiServer._bt_timerange
|
or not ApiServer._bt_timerange
|
||||||
or lastconfig.get('stake_amount') != btconfig.get('stake_amount')
|
|
||||||
or lastconfig.get('enable_protections') != btconfig.get('enable_protections')
|
|
||||||
or lastconfig.get('protections') != btconfig.get('protections', [])
|
|
||||||
or lastconfig.get('timeframe') != strat.timeframe
|
or lastconfig.get('timeframe') != strat.timeframe
|
||||||
):
|
):
|
||||||
lastconfig['timerange'] = btconfig['timerange']
|
|
||||||
lastconfig['protections'] = btconfig.get('protections', [])
|
|
||||||
lastconfig['enable_protections'] = btconfig.get('enable_protections')
|
|
||||||
lastconfig['dry_run_wallet'] = btconfig.get('dry_run_wallet')
|
|
||||||
lastconfig['timeframe'] = strat.timeframe
|
|
||||||
ApiServer._bt_data, ApiServer._bt_timerange = ApiServer._bt.load_bt_data()
|
ApiServer._bt_data, ApiServer._bt_timerange = ApiServer._bt.load_bt_data()
|
||||||
|
|
||||||
|
lastconfig['timerange'] = btconfig['timerange']
|
||||||
|
lastconfig['timeframe'] = strat.timeframe
|
||||||
|
|
||||||
|
lastconfig['protections'] = btconfig.get('protections', [])
|
||||||
|
lastconfig['enable_protections'] = btconfig.get('enable_protections')
|
||||||
|
lastconfig['dry_run_wallet'] = btconfig.get('dry_run_wallet')
|
||||||
|
|
||||||
ApiServer._bt.abort = False
|
ApiServer._bt.abort = False
|
||||||
min_date, max_date = ApiServer._bt.backtest_one_strategy(
|
min_date, max_date = ApiServer._bt.backtest_one_strategy(
|
||||||
strat, ApiServer._bt_data, ApiServer._bt_timerange)
|
strat, ApiServer._bt_data, ApiServer._bt_timerange)
|
||||||
|
|
||||||
ApiServer._bt.results = generate_backtest_stats(
|
ApiServer._bt.results = generate_backtest_stats(
|
||||||
ApiServer._bt_data, ApiServer._bt.all_results,
|
ApiServer._bt_data, ApiServer._bt.all_results,
|
||||||
min_date=min_date, max_date=max_date)
|
min_date=min_date, max_date=max_date)
|
||||||
|
Loading…
Reference in New Issue
Block a user