def test_hyperoptlossresolver_noname(default_conf): with pytest.raises( OperationalException, match= "No Hyperopt loss set. Please use `--hyperopt-loss` to specify " "the Hyperopt-Loss class to use."): HyperOptLossResolver.load_hyperoptloss(default_conf)
def test_loss_calculation_prefer_correct_trade_count(default_conf, hyperopt_results) -> None: hl = HyperOptLossResolver(default_conf).hyperoptloss correct = hl.hyperopt_loss_function(hyperopt_results, 600) over = hl.hyperopt_loss_function(hyperopt_results, 600 + 100) under = hl.hyperopt_loss_function(hyperopt_results, 600 - 100) assert over > correct assert under > correct
def test_loss_calculation_prefer_shorter_trades(default_conf, hyperopt_results) -> None: resultsb = hyperopt_results.copy() resultsb.loc[1, 'trade_duration'] = 20 hl = HyperOptLossResolver(default_conf).hyperoptloss longer = hl.hyperopt_loss_function(hyperopt_results, 100) shorter = hl.hyperopt_loss_function(resultsb, 100) assert shorter < longer
def test_loss_calculation_has_limited_profit(default_conf, hyperopt_results) -> None: results_over = hyperopt_results.copy() results_over['profit_percent'] = hyperopt_results['profit_percent'] * 2 results_under = hyperopt_results.copy() results_under['profit_percent'] = hyperopt_results['profit_percent'] / 2 hl = HyperOptLossResolver(default_conf).hyperoptloss correct = hl.hyperopt_loss_function(hyperopt_results, 600) over = hl.hyperopt_loss_function(results_over, 600) under = hl.hyperopt_loss_function(results_under, 600) assert over < correct assert under > correct
def test_onlyprofit_loss_prefers_higher_profits(default_conf, hyperopt_results) -> None: results_over = hyperopt_results.copy() results_over['profit_percent'] = hyperopt_results['profit_percent'] * 2 results_under = hyperopt_results.copy() results_under['profit_percent'] = hyperopt_results['profit_percent'] / 2 default_conf.update({'hyperopt_loss': 'OnlyProfitHyperOptLoss'}) hl = HyperOptLossResolver(default_conf).hyperoptloss correct = hl.hyperopt_loss_function(hyperopt_results, len(hyperopt_results), datetime(2019, 1, 1), datetime(2019, 5, 1)) over = hl.hyperopt_loss_function(results_over, len(hyperopt_results), datetime(2019, 1, 1), datetime(2019, 5, 1)) under = hl.hyperopt_loss_function(results_under, len(hyperopt_results), datetime(2019, 1, 1), datetime(2019, 5, 1)) assert over < correct assert under > correct
def __init__(self, config: Dict[str, Any]) -> None: self.config = config self.backtesting = Backtesting(self.config) if not self.config.get('hyperopt'): self.custom_hyperopt = HyperOptAuto(self.config) else: self.custom_hyperopt = HyperOptResolver.load_hyperopt(self.config) self.custom_hyperopt.strategy = self.backtesting.strategy self.custom_hyperoptloss = HyperOptLossResolver.load_hyperoptloss(self.config) self.calculate_loss = self.custom_hyperoptloss.hyperopt_loss_function time_now = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") strategy = str(self.config['strategy']) self.results_file = (self.config['user_data_dir'] / 'hyperopt_results' / f'strategy_{strategy}_hyperopt_results_{time_now}.pickle') self.data_pickle_file = (self.config['user_data_dir'] / 'hyperopt_results' / 'hyperopt_tickerdata.pkl') self.total_epochs = config.get('epochs', 0) self.current_best_loss = 100 self.clean_hyperopt() self.num_epochs_saved = 0 # Previous evaluations self.epochs: List = [] # Populate functions here (hasattr is slow so should not be run during "regular" operations) if hasattr(self.custom_hyperopt, 'populate_indicators'): self.backtesting.strategy.advise_indicators = ( # type: ignore self.custom_hyperopt.populate_indicators) # type: ignore if hasattr(self.custom_hyperopt, 'populate_buy_trend'): self.backtesting.strategy.advise_buy = ( # type: ignore self.custom_hyperopt.populate_buy_trend) # type: ignore if hasattr(self.custom_hyperopt, 'populate_sell_trend'): self.backtesting.strategy.advise_sell = ( # type: ignore self.custom_hyperopt.populate_sell_trend) # type: ignore # Use max_open_trades for hyperopt as well, except --disable-max-market-positions is set if self.config.get('use_max_market_positions', True): self.max_open_trades = self.config['max_open_trades'] else: logger.debug('Ignoring max_open_trades (--disable-max-market-positions was used) ...') self.max_open_trades = 0 self.position_stacking = self.config.get('position_stacking', False) if self.has_space('sell'): # Make sure use_sell_signal is enabled if 'ask_strategy' not in self.config: self.config['ask_strategy'] = {} self.config['ask_strategy']['use_sell_signal'] = True self.print_all = self.config.get('print_all', False) self.hyperopt_table_header = 0 self.print_colorized = self.config.get('print_colorized', False) self.print_json = self.config.get('print_json', False)
def __init__(self, config: Dict[str, Any]) -> None: self.config = config self.backtesting = Backtesting(self.config) self.custom_hyperopt = HyperOptResolver(self.config).hyperopt self.custom_hyperoptloss = HyperOptLossResolver( self.config).hyperoptloss self.calculate_loss = self.custom_hyperoptloss.hyperopt_loss_function self.trials_file = (self.config['user_data_dir'] / 'hyperopt_results' / 'hyperopt_results.pickle') self.tickerdata_pickle = (self.config['user_data_dir'] / 'hyperopt_results' / 'hyperopt_tickerdata.pkl') self.total_epochs = config.get('epochs', 0) self.current_best_loss = 100 if not self.config.get('hyperopt_continue'): self.clean_hyperopt() else: logger.info("Continuing on previous hyperopt results.") self.num_trials_saved = 0 # Previous evaluations self.trials: List = [] # Populate functions here (hasattr is slow so should not be run during "regular" operations) if hasattr(self.custom_hyperopt, 'populate_indicators'): self.backtesting.strategy.advise_indicators = \ self.custom_hyperopt.populate_indicators # type: ignore if hasattr(self.custom_hyperopt, 'populate_buy_trend'): self.backtesting.strategy.advise_buy = \ self.custom_hyperopt.populate_buy_trend # type: ignore if hasattr(self.custom_hyperopt, 'populate_sell_trend'): self.backtesting.strategy.advise_sell = \ self.custom_hyperopt.populate_sell_trend # type: ignore # Use max_open_trades for hyperopt as well, except --disable-max-market-positions is set if self.config.get('use_max_market_positions', True): self.max_open_trades = self.config['max_open_trades'] else: logger.debug( 'Ignoring max_open_trades (--disable-max-market-positions was used) ...' ) self.max_open_trades = 0 self.position_stacking = self.config.get('position_stacking', False) if self.has_space('sell'): # Make sure use_sell_signal is enabled if 'ask_strategy' not in self.config: self.config['ask_strategy'] = {} self.config['ask_strategy']['use_sell_signal'] = True self.print_all = self.config.get('print_all', False) self.print_colorized = self.config.get('print_colorized', False) self.print_json = self.config.get('print_json', False)
def __init__(self, config: Dict[str, Any]) -> None: self.buy_space: List[Dimension] = [] self.sell_space: List[Dimension] = [] self.protection_space: List[Dimension] = [] self.roi_space: List[Dimension] = [] self.stoploss_space: List[Dimension] = [] self.trailing_space: List[Dimension] = [] self.dimensions: List[Dimension] = [] self.config = config self.backtesting = Backtesting(self.config) self.pairlist = self.backtesting.pairlists.whitelist if not self.config.get('hyperopt'): self.custom_hyperopt = HyperOptAuto(self.config) else: raise OperationalException( "Using separate Hyperopt files has been removed in 2021.9. Please convert " "your existing Hyperopt file to the new Hyperoptable strategy interface") self.backtesting._set_strategy(self.backtesting.strategylist[0]) self.custom_hyperopt.strategy = self.backtesting.strategy self.custom_hyperoptloss = HyperOptLossResolver.load_hyperoptloss(self.config) self.calculate_loss = self.custom_hyperoptloss.hyperopt_loss_function time_now = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") strategy = str(self.config['strategy']) self.results_file: Path = (self.config['user_data_dir'] / 'hyperopt_results' / f'strategy_{strategy}_{time_now}.fthypt') self.data_pickle_file = (self.config['user_data_dir'] / 'hyperopt_results' / 'hyperopt_tickerdata.pkl') self.total_epochs = config.get('epochs', 0) self.current_best_loss = 100 self.clean_hyperopt() self.num_epochs_saved = 0 self.current_best_epoch: Optional[Dict[str, Any]] = None # Use max_open_trades for hyperopt as well, except --disable-max-market-positions is set if self.config.get('use_max_market_positions', True): self.max_open_trades = self.config['max_open_trades'] else: logger.debug('Ignoring max_open_trades (--disable-max-market-positions was used) ...') self.max_open_trades = 0 self.position_stacking = self.config.get('position_stacking', False) if HyperoptTools.has_space(self.config, 'sell'): # Make sure use_sell_signal is enabled if 'ask_strategy' not in self.config: self.config['ask_strategy'] = {} self.config['ask_strategy']['use_sell_signal'] = True self.print_all = self.config.get('print_all', False) self.hyperopt_table_header = 0 self.print_colorized = self.config.get('print_colorized', False) self.print_json = self.config.get('print_json', False)
def test_hyperoptlossresolver(mocker, default_conf, caplog) -> None: hl = DefaultHyperOptLoss mocker.patch( 'freqtrade.resolvers.hyperopt_resolver.HyperOptLossResolver._load_hyperoptloss', MagicMock(return_value=hl)) x = HyperOptLossResolver(default_conf, ).hyperoptloss assert hasattr(x, "hyperopt_loss_function")
def test_hyperoptlossresolver(mocker, default_conf) -> None: hl = ShortTradeDurHyperOptLoss mocker.patch( 'freqtrade.resolvers.hyperopt_resolver.HyperOptLossResolver.load_object', MagicMock(return_value=hl())) default_conf.update({'hyperopt_loss': 'SharpeHyperOptLossDaily'}) x = HyperOptLossResolver.load_hyperoptloss(default_conf) assert hasattr(x, "hyperopt_loss_function")
def test_loss_calculation_prefer_shorter_trades(default_conf, hyperopt_results) -> None: resultsb = hyperopt_results.copy() resultsb.loc[1, 'trade_duration'] = 20 hl = HyperOptLossResolver.load_hyperoptloss(default_conf) longer = hl.hyperopt_loss_function(hyperopt_results, 100, datetime(2019, 1, 1), datetime(2019, 5, 1)) shorter = hl.hyperopt_loss_function(resultsb, 100, datetime(2019, 1, 1), datetime(2019, 5, 1)) assert shorter < longer
def test_loss_calculation_prefer_correct_trade_count(default_conf, hyperopt_results) -> None: hl = HyperOptLossResolver.load_hyperoptloss(default_conf) correct = hl.hyperopt_loss_function(hyperopt_results, 600, datetime(2019, 1, 1), datetime(2019, 5, 1)) over = hl.hyperopt_loss_function(hyperopt_results, 600 + 100, datetime(2019, 1, 1), datetime(2019, 5, 1)) under = hl.hyperopt_loss_function(hyperopt_results, 600 - 100, datetime(2019, 1, 1), datetime(2019, 5, 1)) assert over > correct assert under > correct
def test_loss_calculation_has_limited_profit(default_conf, hyperopt_results) -> None: results_over = hyperopt_results.copy() results_over['profit_percent'] = hyperopt_results['profit_percent'] * 2 results_under = hyperopt_results.copy() results_under['profit_percent'] = hyperopt_results['profit_percent'] / 2 hl = HyperOptLossResolver.load_hyperoptloss(default_conf) correct = hl.hyperopt_loss_function(hyperopt_results, 600, datetime(2019, 1, 1), datetime(2019, 5, 1)) over = hl.hyperopt_loss_function(results_over, 600, datetime(2019, 1, 1), datetime(2019, 5, 1)) under = hl.hyperopt_loss_function(results_under, 600, datetime(2019, 1, 1), datetime(2019, 5, 1)) assert over < correct assert under > correct
def test_sortino_loss_daily_prefers_higher_profits(default_conf, hyperopt_results) -> None: results_over = hyperopt_results.copy() results_over['profit_percent'] = hyperopt_results['profit_percent'] * 2 results_under = hyperopt_results.copy() results_under['profit_percent'] = hyperopt_results['profit_percent'] / 2 default_conf.update({'hyperopt_loss': 'SortinoHyperOptLossDaily'}) hl = HyperOptLossResolver.load_hyperoptloss(default_conf) correct = hl.hyperopt_loss_function(hyperopt_results, len(hyperopt_results), datetime(2019, 1, 1), datetime(2019, 5, 1)) over = hl.hyperopt_loss_function(results_over, len(hyperopt_results), datetime(2019, 1, 1), datetime(2019, 5, 1)) under = hl.hyperopt_loss_function(results_under, len(hyperopt_results), datetime(2019, 1, 1), datetime(2019, 5, 1)) assert over < correct assert under > correct
def test_loss_calculation_has_limited_profit(hyperopt_conf, hyperopt_results) -> None: results_over = hyperopt_results.copy() results_over['profit_ratio'] = hyperopt_results['profit_ratio'] * 2 results_under = hyperopt_results.copy() results_under['profit_ratio'] = hyperopt_results['profit_ratio'] / 2 hyperopt_conf.update({'hyperopt_loss': "ShortTradeDurHyperOptLoss"}) hl = HyperOptLossResolver.load_hyperoptloss(hyperopt_conf) correct = hl.hyperopt_loss_function(hyperopt_results, 600, datetime(2019, 1, 1), datetime(2019, 5, 1)) over = hl.hyperopt_loss_function(results_over, 600, datetime(2019, 1, 1), datetime(2019, 5, 1)) under = hl.hyperopt_loss_function(results_under, 600, datetime(2019, 1, 1), datetime(2019, 5, 1)) assert over < correct assert under > correct
def test_loss_functions_better_profits(default_conf, hyperopt_results, lossfunction) -> None: results_over = hyperopt_results.copy() results_over['profit_abs'] = hyperopt_results['profit_abs'] * 2 + 0.2 results_over['profit_ratio'] = hyperopt_results['profit_ratio'] * 2 results_under = hyperopt_results.copy() results_under['profit_abs'] = hyperopt_results['profit_abs'] / 2 - 0.2 results_under['profit_ratio'] = hyperopt_results['profit_ratio'] / 2 default_conf.update({'hyperopt_loss': lossfunction}) hl = HyperOptLossResolver.load_hyperoptloss(default_conf) correct = hl.hyperopt_loss_function(hyperopt_results, len(hyperopt_results), datetime(2019, 1, 1), datetime(2019, 5, 1)) over = hl.hyperopt_loss_function(results_over, len(results_over), datetime(2019, 1, 1), datetime(2019, 5, 1)) under = hl.hyperopt_loss_function(results_under, len(results_under), datetime(2019, 1, 1), datetime(2019, 5, 1)) assert over < correct assert under > correct
def test_loss_functions_better_profits(default_conf, hyperopt_results, lossfunction) -> None: results_over = hyperopt_results.copy() results_over['profit_abs'] = hyperopt_results['profit_abs'] * 2 + 0.2 results_over['profit_ratio'] = hyperopt_results['profit_ratio'] * 2 results_under = hyperopt_results.copy() results_under['profit_abs'] = hyperopt_results['profit_abs'] / 2 - 0.2 results_under['profit_ratio'] = hyperopt_results['profit_ratio'] / 2 default_conf.update({'hyperopt_loss': lossfunction}) hl = HyperOptLossResolver.load_hyperoptloss(default_conf) correct = hl.hyperopt_loss_function( hyperopt_results, trade_count=len(hyperopt_results), min_date=datetime(2019, 1, 1), max_date=datetime(2019, 5, 1), config=default_conf, processed=None, backtest_stats={'profit_total': hyperopt_results['profit_abs'].sum()}) over = hl.hyperopt_loss_function( results_over, trade_count=len(results_over), min_date=datetime(2019, 1, 1), max_date=datetime(2019, 5, 1), config=default_conf, processed=None, backtest_stats={'profit_total': results_over['profit_abs'].sum()}) under = hl.hyperopt_loss_function( results_under, trade_count=len(results_under), min_date=datetime(2019, 1, 1), max_date=datetime(2019, 5, 1), config=default_conf, processed=None, backtest_stats={'profit_total': results_under['profit_abs'].sum()}) assert over < correct assert under > correct
def __init__(self, config: Dict[str, Any]) -> None: super().__init__(config) self.custom_hyperopt = HyperOptResolver(self.config).hyperopt self.custom_hyperoptloss = HyperOptLossResolver( self.config).hyperoptloss self.calculate_loss = self.custom_hyperoptloss.hyperopt_loss_function self.total_tries = config.get('epochs', 0) self.current_best_loss = 100 if not self.config.get('hyperopt_continue'): self.clean_hyperopt() else: logger.info("Continuing on previous hyperopt results.") # Previous evaluations self.trials_file = TRIALSDATA_PICKLE self.trials: List = [] # Populate functions here (hasattr is slow so should not be run during "regular" operations) if hasattr(self.custom_hyperopt, 'populate_buy_trend'): self.advise_buy = self.custom_hyperopt.populate_buy_trend # type: ignore if hasattr(self.custom_hyperopt, 'populate_sell_trend'): self.advise_sell = self.custom_hyperopt.populate_sell_trend # type: ignore # Use max_open_trades for hyperopt as well, except --disable-max-market-positions is set if self.config.get('use_max_market_positions', True): self.max_open_trades = self.config['max_open_trades'] else: logger.debug( 'Ignoring max_open_trades (--disable-max-market-positions was used) ...' ) self.max_open_trades = 0 self.position_stacking = self.config.get('position_stacking', False),
def test_hyperoptlossresolver_wrongname(mocker, default_conf, caplog) -> None: default_conf.update({'hyperopt_loss': "NonExistingLossClass"}) with pytest.raises(OperationalException, match=r'Impossible to load HyperoptLoss.*'): HyperOptLossResolver(default_conf, ).hyperopt