diff --git a/freqtrade/optimize/base_analysis.py b/freqtrade/optimize/base_analysis.py index ab7e6af0a..5ee5a4466 100644 --- a/freqtrade/optimize/base_analysis.py +++ b/freqtrade/optimize/base_analysis.py @@ -49,7 +49,7 @@ class BaseAnalysis: timestamp = int(dt.replace(tzinfo=timezone.utc).timestamp()) return timestamp - def prepare_data(self, varholder: VarHolder, pairs_to_load: List[DataFrame]): + def prepare_data(self, varholder: VarHolder, pairs_to_load: List[DataFrame], backtesting=None): if 'freqai' in self.local_config and 'identifier' in self.local_config['freqai']: # purge previous data if the freqai model is defined @@ -70,7 +70,8 @@ class BaseAnalysis: # Don't re-calculate fee per pair, as fee might differ per pair. prepare_data_config['fee'] = self._fee - backtesting = Backtesting(prepare_data_config, self.exchange) + if backtesting is None: + backtesting = Backtesting(prepare_data_config, self.exchange) backtesting._set_strategy(backtesting.strategylist[0]) varholder.data, varholder.timerange = backtesting.load_bt_data() diff --git a/freqtrade/optimize/lookahead_analysis.py b/freqtrade/optimize/lookahead_analysis.py index 80418da95..00283da91 100755 --- a/freqtrade/optimize/lookahead_analysis.py +++ b/freqtrade/optimize/lookahead_analysis.py @@ -13,6 +13,7 @@ from freqtrade.exchange import timeframe_to_minutes from freqtrade.loggers.set_log_levels import (reduce_verbosity_for_bias_tester, restore_verbosity_for_bias_tester) from freqtrade.optimize.backtesting import Backtesting +from freqtrade.optimize.base_analysis import BaseAnalysis, VarHolder logger = logging.getLogger(__name__) @@ -39,29 +40,18 @@ class Analysis: self.has_bias = False -class LookaheadAnalysis: +class LookaheadAnalysis(BaseAnalysis): def __init__(self, config: Dict[str, Any], strategy_obj: Dict): - self.failed_bias_check = True - self.full_varHolder = VarHolder() + + super().__init__(config, strategy_obj) self.entry_varHolders: List[VarHolder] = [] self.exit_varHolders: List[VarHolder] = [] - self.exchange: Optional[Any] = None - self._fee = None - # pull variables the scope of the lookahead_analysis-instance - self.local_config = deepcopy(config) - self.local_config['strategy'] = strategy_obj['name'] self.current_analysis = Analysis() self.minimum_trade_amount = config['minimum_trade_amount'] self.targeted_trade_amount = config['targeted_trade_amount'] - self.strategy_obj = strategy_obj - - @staticmethod - def dt_to_timestamp(dt: datetime): - timestamp = int(dt.replace(tzinfo=timezone.utc).timestamp()) - return timestamp @staticmethod def get_result(backtesting: Backtesting, processed: DataFrame): @@ -129,57 +119,41 @@ class LookaheadAnalysis: f"{col_name[0]}. " f"{str(self_value)} != {str(other_value)}") - def prepare_data(self, varholder: VarHolder, pairs_to_load: List[DataFrame]): + def prepare_data(self, varholder: VarHolder, pairs_to_load: List[DataFrame], backtesting=None): - if 'freqai' in self.local_config and 'identifier' in self.local_config['freqai']: - # purge previous data if the freqai model is defined - # (to be sure nothing is carried over from older backtests) - path_to_current_identifier = ( - Path(f"{self.local_config['user_data_dir']}/models/" - f"{self.local_config['freqai']['identifier']}").resolve()) - # remove folder and its contents - if Path.exists(path_to_current_identifier): - shutil.rmtree(path_to_current_identifier) + super().prepare_data(varholder, pairs_to_load, backtesting) - prepare_data_config = deepcopy(self.local_config) - prepare_data_config['timerange'] = (str(self.dt_to_timestamp(varholder.from_dt)) + "-" + - str(self.dt_to_timestamp(varholder.to_dt))) - prepare_data_config['exchange']['pair_whitelist'] = pairs_to_load + # if 'freqai' in self.local_config and 'identifier' in self.local_config['freqai']: + # # purge previous data if the freqai model is defined + # # (to be sure nothing is carried over from older backtests) + # path_to_current_identifier = ( + # Path(f"{self.local_config['user_data_dir']}/models/" + # f"{self.local_config['freqai']['identifier']}").resolve()) + # # remove folder and its contents + # if Path.exists(path_to_current_identifier): + # shutil.rmtree(path_to_current_identifier) - if self._fee is not None: - # Don't re-calculate fee per pair, as fee might differ per pair. - prepare_data_config['fee'] = self._fee + # prepare_data_config = deepcopy(self.local_config) + # prepare_data_config['timerange'] = (str(self.dt_to_timestamp(varholder.from_dt)) + "-" + + # str(self.dt_to_timestamp(varholder.to_dt))) + # prepare_data_config['exchange']['pair_whitelist'] = pairs_to_load - backtesting = Backtesting(prepare_data_config, self.exchange) + # if self._fee is not None: + # # Don't re-calculate fee per pair, as fee might differ per pair. + # prepare_data_config['fee'] = self._fee + + # backtesting = Backtesting(prepare_data_config, self.exchange) self.exchange = backtesting.exchange self._fee = backtesting.fee - backtesting._set_strategy(backtesting.strategylist[0]) + # backtesting._set_strategy(backtesting.strategylist[0]) - varholder.data, varholder.timerange = backtesting.load_bt_data() - backtesting.load_bt_data_detail() - varholder.timeframe = backtesting.timeframe + # varholder.data, varholder.timerange = backtesting.load_bt_data() + # backtesting.load_bt_data_detail() + # varholder.timeframe = backtesting.timeframe - varholder.indicators = backtesting.strategy.advise_all_indicators(varholder.data) + # varholder.indicators = backtesting.strategy.advise_all_indicators(varholder.data) varholder.result = self.get_result(backtesting, varholder.indicators) - def fill_full_varholder(self): - self.full_varHolder = VarHolder() - - # define datetime in human-readable format - parsed_timerange = TimeRange.parse_timerange(self.local_config['timerange']) - - if parsed_timerange.startdt is None: - self.full_varHolder.from_dt = datetime.fromtimestamp(0, tz=timezone.utc) - else: - self.full_varHolder.from_dt = parsed_timerange.startdt - - if parsed_timerange.stopdt is None: - self.full_varHolder.to_dt = datetime.utcnow() - else: - self.full_varHolder.to_dt = parsed_timerange.stopdt - - self.prepare_data(self.full_varHolder, self.local_config['pairs']) - def fill_entry_and_exit_varHolders(self, result_row): # entry_varHolder entry_varHolder = VarHolder() @@ -246,8 +220,7 @@ class LookaheadAnalysis: def start(self) -> None: - # first make a single backtest - self.fill_full_varholder() + super().start() reduce_verbosity_for_bias_tester()