def test_continue_hyperopt(mocker, default_conf, caplog): patch_exchange(mocker) default_conf.update({'config': 'config.json.example', 'hyperopt': 'DefaultHyperOpt', 'epochs': 1, 'timerange': None, 'spaces': 'default', 'hyperopt_jobs': 1, 'hyperopt_continue': True }) mocker.patch("freqtrade.optimize.hyperopt.Path.is_file", MagicMock(return_value=True)) unlinkmock = mocker.patch("freqtrade.optimize.hyperopt.Path.unlink", MagicMock()) Hyperopt(default_conf) assert unlinkmock.call_count == 0 assert log_has(f"Continuing on previous hyperopt results.", caplog)
def test_start_filelock(mocker, hyperopt_conf, caplog) -> None: hyperopt_mock = MagicMock( side_effect=Timeout(Hyperopt.get_lock_filename(hyperopt_conf))) patched_configuration_load_config_file(mocker, hyperopt_conf) mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.__init__', hyperopt_mock) patch_exchange(mocker) args = [ 'hyperopt', '--config', 'config.json', '--hyperopt', 'DefaultHyperOpt', '--hyperopt-loss', 'SharpeHyperOptLossDaily', '--epochs', '5' ] pargs = get_args(args) start_hyperopt(pargs) assert log_has("Another running instance of freqtrade Hyperopt detected.", caplog)
def test_clean_hyperopt(mocker, default_conf, caplog): patch_exchange(mocker) default_conf.update({ 'config': 'config.json.example', 'epochs': 1, 'timerange': None, 'spaces': 'all', 'hyperopt_jobs': 1, }) mocker.patch("freqtrade.optimize.hyperopt.Path.is_file", MagicMock(return_value=True)) unlinkmock = mocker.patch("freqtrade.optimize.hyperopt.Path.unlink", MagicMock()) h = Hyperopt(default_conf) assert unlinkmock.call_count == 2 assert log_has(f"Removing `{h.tickerdata_pickle}`.", caplog)
def get_pickle_data(args: Dict[str, Any]) -> List[Union[List, int]]: """ Fetches the pickle file and returns its raw data. Returns: List[List[], int]: pickle data, total epochs """ config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) trials_file = (config['user_data_dir'] / 'hyperopt_results' / 'hyperopt_results.pickle') # Previous evaluations trials = Hyperopt.load_previous_results(trials_file) total_epochs = len(trials) return [trials, total_epochs]
def test_resuming_previous_hyperopt_results_succeeds(mocker, default_conf) -> None: trials = create_trials(mocker) conf = deepcopy(default_conf) conf.update({'config': 'config.json.example'}) conf.update({'epochs': 1}) conf.update({'mongodb': False}) conf.update({'timerange': None}) conf.update({'spaces': 'all'}) mocker.patch('freqtrade.optimize.hyperopt.os.path.exists', return_value=True) mocker.patch('freqtrade.optimize.hyperopt.len', return_value=len(trials.results)) mock_read = mocker.patch( 'freqtrade.optimize.hyperopt.Hyperopt.read_trials', return_value=trials) mock_save = mocker.patch( 'freqtrade.optimize.hyperopt.Hyperopt.save_trials', return_value=None) mocker.patch('freqtrade.optimize.hyperopt.sorted', return_value=trials.results) mocker.patch('freqtrade.optimize.hyperopt.load_data', MagicMock()) mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value={}) mocker.patch('freqtrade.optimize.hyperopt.hyperopt_optimize_conf', return_value=conf) StrategyResolver({'strategy': 'DefaultStrategy'}) hyperopt = Hyperopt(conf) hyperopt.trials = trials hyperopt.tickerdata_to_dataframe = MagicMock() hyperopt.start() mock_read.assert_called_once() mock_save.assert_called_once() current_tries = hyperopt.current_tries total_tries = hyperopt.total_tries assert current_tries == len(trials.results) assert total_tries == (current_tries + len(trials.results))
def test_start_calls_fmin(mocker, default_conf) -> None: trials = create_trials(mocker) mocker.patch('freqtrade.optimize.hyperopt.sorted', return_value=trials.results) mocker.patch('freqtrade.optimize.hyperopt.load_data', MagicMock()) mock_fmin = mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value={}) conf = deepcopy(default_conf) conf.update({'config': 'config.json.example'}) conf.update({'epochs': 1}) conf.update({'mongodb': False}) conf.update({'timerange': None}) conf.update({'spaces': 'all'}) hyperopt = Hyperopt(conf) hyperopt.trials = trials hyperopt.tickerdata_to_dataframe = MagicMock() hyperopt.start() mock_fmin.assert_called_once()
def test_in_strategy_auto_hyperopt(mocker, hyperopt_conf, tmpdir, fee) -> None: patch_exchange(mocker) mocker.patch('freqtrade.exchange.Exchange.get_fee', fee) (Path(tmpdir) / 'hyperopt_results').mkdir(parents=True) # No hyperopt needed hyperopt_conf.update({ 'strategy': 'HyperoptableStrategy', 'user_data_dir': Path(tmpdir), 'hyperopt_random_state': 42, 'spaces': ['all'] }) hyperopt = Hyperopt(hyperopt_conf) hyperopt.backtesting.exchange.get_max_leverage = MagicMock( return_value=1.0) assert isinstance(hyperopt.custom_hyperopt, HyperOptAuto) assert isinstance(hyperopt.backtesting.strategy.buy_rsi, IntParameter) assert hyperopt.backtesting.strategy.buy_rsi.in_space is True assert hyperopt.backtesting.strategy.buy_rsi.value == 35 assert hyperopt.backtesting.strategy.sell_rsi.value == 74 assert hyperopt.backtesting.strategy.protection_cooldown_lookback.value == 30 buy_rsi_range = hyperopt.backtesting.strategy.buy_rsi.range assert isinstance(buy_rsi_range, range) # Range from 0 - 50 (inclusive) assert len(list(buy_rsi_range)) == 51 hyperopt.start() # All values should've changed. assert hyperopt.backtesting.strategy.protection_cooldown_lookback.value != 30 assert hyperopt.backtesting.strategy.buy_rsi.value != 35 assert hyperopt.backtesting.strategy.sell_rsi.value != 74 hyperopt.custom_hyperopt.generate_estimator = lambda *args, **kwargs: 'ET1' with pytest.raises(OperationalException, match="Estimator ET1 not supported."): hyperopt.get_optimizer([], 2)
def test_generate_optimizer(mocker, hyperopt_conf) -> None: hyperopt_conf.update({ 'spaces': 'all', 'hyperopt_min_trades': 1, }) trades = [('TRX/BTC', 0.023117, 0.000233, 100)] labels = ['currency', 'profit_percent', 'profit_abs', 'trade_duration'] backtest_result = pd.DataFrame.from_records(trades, columns=labels) mocker.patch('freqtrade.optimize.hyperopt.Backtesting.backtest', MagicMock(return_value=backtest_result)) mocker.patch( 'freqtrade.optimize.hyperopt.get_timerange', MagicMock(return_value=(Arrow(2017, 12, 10), Arrow(2017, 12, 13)))) patch_exchange(mocker) mocker.patch('freqtrade.optimize.hyperopt.load', MagicMock()) optimizer_param = { 'adx-value': 0, 'fastd-value': 35, 'mfi-value': 0, 'rsi-value': 0, 'adx-enabled': False, 'fastd-enabled': True, 'mfi-enabled': False, 'rsi-enabled': False, 'trigger': 'macd_cross_signal', 'sell-adx-value': 0, 'sell-fastd-value': 75, 'sell-mfi-value': 0, 'sell-rsi-value': 0, 'sell-adx-enabled': False, 'sell-fastd-enabled': True, 'sell-mfi-enabled': False, 'sell-rsi-enabled': False, 'sell-trigger': 'macd_cross_signal', 'roi_t1': 60.0, 'roi_t2': 30.0, 'roi_t3': 20.0, 'roi_p1': 0.01, 'roi_p2': 0.01, 'roi_p3': 0.1, 'stoploss': -0.4, 'trailing_stop': True, 'trailing_stop_positive': 0.02, 'trailing_stop_positive_offset_p1': 0.05, 'trailing_only_offset_is_reached': False, } response_expected = { 'loss': 1.9840569076926293, 'results_explanation': (' 1 trades. 1/0/0 Wins/Draws/Losses. ' 'Avg profit 2.31%. Median profit 2.31%. Total profit ' '0.00023300 BTC ( 2.31\N{GREEK CAPITAL LETTER SIGMA}%). ' 'Avg duration 100.0 min.').encode(locale.getpreferredencoding(), 'replace').decode('utf-8'), 'params_details': { 'buy': { 'adx-enabled': False, 'adx-value': 0, 'fastd-enabled': True, 'fastd-value': 35, 'mfi-enabled': False, 'mfi-value': 0, 'rsi-enabled': False, 'rsi-value': 0, 'trigger': 'macd_cross_signal' }, 'roi': { 0: 0.12000000000000001, 20.0: 0.02, 50.0: 0.01, 110.0: 0 }, 'sell': { 'sell-adx-enabled': False, 'sell-adx-value': 0, 'sell-fastd-enabled': True, 'sell-fastd-value': 75, 'sell-mfi-enabled': False, 'sell-mfi-value': 0, 'sell-rsi-enabled': False, 'sell-rsi-value': 0, 'sell-trigger': 'macd_cross_signal' }, 'stoploss': { 'stoploss': -0.4 }, 'trailing': { 'trailing_only_offset_is_reached': False, 'trailing_stop': True, 'trailing_stop_positive': 0.02, 'trailing_stop_positive_offset': 0.07 } }, 'params_dict': optimizer_param, 'results_metrics': { 'avg_profit': 2.3117, 'draws': 0, 'duration': 100.0, 'losses': 0, 'winsdrawslosses': ' 1 0 0', 'median_profit': 2.3117, 'profit': 2.3117, 'total_profit': 0.000233, 'trade_count': 1, 'wins': 1 }, 'total_profit': 0.00023300 } hyperopt = Hyperopt(hyperopt_conf) hyperopt.dimensions = hyperopt.hyperopt_space() generate_optimizer_value = hyperopt.generate_optimizer( list(optimizer_param.values())) assert generate_optimizer_value == response_expected
def test_generate_optimizer(mocker, hyperopt_conf) -> None: hyperopt_conf.update({ 'spaces': 'all', 'hyperopt_min_trades': 1, }) backtest_result = { 'results': pd.DataFrame({ "pair": ["UNITTEST/BTC", "UNITTEST/BTC", "UNITTEST/BTC", "UNITTEST/BTC"], "profit_ratio": [0.003312, 0.010801, 0.013803, 0.002780], "profit_abs": [0.000003, 0.000011, 0.000014, 0.000003], "open_date": [ Arrow(2017, 11, 14, 19, 32, 00).datetime, Arrow(2017, 11, 14, 21, 36, 00).datetime, Arrow(2017, 11, 14, 22, 12, 00).datetime, Arrow(2017, 11, 14, 22, 44, 00).datetime ], "close_date": [ Arrow(2017, 11, 14, 21, 35, 00).datetime, Arrow(2017, 11, 14, 22, 10, 00).datetime, Arrow(2017, 11, 14, 22, 43, 00).datetime, Arrow(2017, 11, 14, 22, 58, 00).datetime ], "open_rate": [0.002543, 0.003003, 0.003089, 0.003214], "close_rate": [0.002546, 0.003014, 0.003103, 0.003217], "trade_duration": [123, 34, 31, 14], "is_open": [False, False, False, True], "stake_amount": [0.01, 0.01, 0.01, 0.01], "sell_reason": [ SellType.ROI, SellType.STOP_LOSS, SellType.ROI, SellType.FORCE_SELL ] }), 'config': hyperopt_conf, 'locks': [], 'rejected_signals': 20, 'timedout_entry_orders': 0, 'timedout_exit_orders': 0, 'final_balance': 1000, } mocker.patch('freqtrade.optimize.hyperopt.Backtesting.backtest', return_value=backtest_result) mocker.patch('freqtrade.optimize.hyperopt.get_timerange', return_value=(Arrow(2017, 12, 10), Arrow(2017, 12, 13))) patch_exchange(mocker) mocker.patch.object(Path, 'open') mocker.patch( 'freqtrade.configuration.config_validation.validate_config_schema') mocker.patch('freqtrade.optimize.hyperopt.load', return_value={'XRP/BTC': None}) optimizer_param = { 'buy_plusdi': 0.02, 'buy_rsi': 35, 'sell_minusdi': 0.02, 'sell_rsi': 75, 'protection_cooldown_lookback': 20, 'protection_enabled': True, 'roi_t1': 60.0, 'roi_t2': 30.0, 'roi_t3': 20.0, 'roi_p1': 0.01, 'roi_p2': 0.01, 'roi_p3': 0.1, 'stoploss': -0.4, 'trailing_stop': True, 'trailing_stop_positive': 0.02, 'trailing_stop_positive_offset_p1': 0.05, 'trailing_only_offset_is_reached': False, } response_expected = { 'loss': 1.9147239021396234, 'results_explanation': (' 4 trades. 4/0/0 Wins/Draws/Losses. ' 'Avg profit 0.77%. Median profit 0.71%. Total profit ' '0.00003100 BTC ( 0.00%). ' 'Avg duration 0:50:00 min.'), 'params_details': { 'buy': { 'buy_plusdi': 0.02, 'buy_rsi': 35, }, 'roi': { "0": 0.12000000000000001, "20.0": 0.02, "50.0": 0.01, "110.0": 0 }, 'protection': { 'protection_cooldown_lookback': 20, 'protection_enabled': True, }, 'sell': { 'sell_minusdi': 0.02, 'sell_rsi': 75, }, 'stoploss': { 'stoploss': -0.4 }, 'trailing': { 'trailing_only_offset_is_reached': False, 'trailing_stop': True, 'trailing_stop_positive': 0.02, 'trailing_stop_positive_offset': 0.07 } }, 'params_dict': optimizer_param, 'params_not_optimized': { 'buy': {}, 'protection': {}, 'sell': {} }, 'results_metrics': ANY, 'total_profit': 3.1e-08 } hyperopt = Hyperopt(hyperopt_conf) hyperopt.min_date = Arrow(2017, 12, 10) hyperopt.max_date = Arrow(2017, 12, 13) hyperopt.init_spaces() hyperopt.dimensions = hyperopt.dimensions generate_optimizer_value = hyperopt.generate_optimizer( list(optimizer_param.values())) assert generate_optimizer_value == response_expected
def test_generate_optimizer(mocker, default_conf) -> None: default_conf.update({'config': 'config.json.example'}) default_conf.update({'timerange': None}) default_conf.update({'spaces': 'all'}) default_conf.update({'hyperopt_min_trades': 1}) trades = [('POWR/BTC', 0.023117, 0.000233, 100)] labels = ['currency', 'profit_percent', 'profit_abs', 'trade_duration'] backtest_result = pd.DataFrame.from_records(trades, columns=labels) mocker.patch('freqtrade.optimize.hyperopt.Backtesting.backtest', MagicMock(return_value=backtest_result)) mocker.patch( 'freqtrade.optimize.hyperopt.get_timeframe', MagicMock(return_value=(Arrow(2017, 12, 10), Arrow(2017, 12, 13)))) patch_exchange(mocker) mocker.patch('freqtrade.optimize.hyperopt.load', MagicMock()) optimizer_param = { 'adx-value': 0, 'fastd-value': 35, 'mfi-value': 0, 'rsi-value': 0, 'adx-enabled': False, 'fastd-enabled': True, 'mfi-enabled': False, 'rsi-enabled': False, 'trigger': 'macd_cross_signal', 'sell-adx-value': 0, 'sell-fastd-value': 75, 'sell-mfi-value': 0, 'sell-rsi-value': 0, 'sell-adx-enabled': False, 'sell-fastd-enabled': True, 'sell-mfi-enabled': False, 'sell-rsi-enabled': False, 'sell-trigger': 'macd_cross_signal', 'roi_t1': 60.0, 'roi_t2': 30.0, 'roi_t3': 20.0, 'roi_p1': 0.01, 'roi_p2': 0.01, 'roi_p3': 0.1, 'stoploss': -0.4, } response_expected = { 'loss': 1.9840569076926293, 'results_explanation': ' 1 trades. Avg profit 2.31%. Total profit 0.00023300 BTC ' '( 2.31Σ%). Avg duration 100.0 mins.', 'params': optimizer_param, 'total_profit': 0.00023300 } hyperopt = Hyperopt(default_conf) hyperopt.dimensions = hyperopt.hyperopt_space() generate_optimizer_value = hyperopt.generate_optimizer( list(optimizer_param.values())) assert generate_optimizer_value == response_expected
def test_print_json_spaces_all(mocker, hyperopt_conf, capsys) -> None: dumper = mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock()) mocker.patch('freqtrade.optimize.hyperopt.file_dump_json') mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data', MagicMock(return_value=(MagicMock(), None))) mocker.patch( 'freqtrade.optimize.hyperopt.get_timerange', MagicMock(return_value=(datetime(2017, 12, 10), datetime(2017, 12, 13)))) parallel = mocker.patch( 'freqtrade.optimize.hyperopt.Hyperopt.run_optimizer_parallel', MagicMock(return_value=[{ 'loss': 1, 'results_explanation': 'foo result', 'params': {}, 'params_details': { 'buy': { 'mfi-value': None }, 'sell': { 'sell-mfi-value': None }, 'roi': {}, 'stoploss': { 'stoploss': None }, 'trailing': { 'trailing_stop': None } }, 'results_metrics': { 'trade_count': 1, 'avg_profit': 0.1, 'total_profit': 0.001, 'profit': 1.0, 'duration': 20.0 } }])) patch_exchange(mocker) hyperopt_conf.update({ 'spaces': 'all', 'hyperopt_jobs': 1, 'print_json': True, }) hyperopt = Hyperopt(hyperopt_conf) hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock() hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={}) hyperopt.start() parallel.assert_called_once() out, err = capsys.readouterr() result_str = ( '{"params":{"mfi-value":null,"sell-mfi-value":null},"minimal_roi"' ':{},"stoploss":null,"trailing_stop":null}') assert result_str in out # noqa: E501 assert dumper.called # Should be called twice, once for historical candle data, once to save evaluations assert dumper.call_count == 2
def test_fmin_best_results(mocker, default_conf, caplog) -> None: fmin_result = { "macd_below_zero": 0, "adx": 1, "adx-value": 15.0, "fastd": 1, "fastd-value": 40.0, "green_candle": 1, "mfi": 0, "over_sar": 0, "rsi": 1, "rsi-value": 37.0, "trigger": 2, "uptrend_long_ema": 1, "uptrend_short_ema": 0, "uptrend_sma": 0, "stoploss": -0.1, "roi_t1": 1, "roi_t2": 2, "roi_t3": 3, "roi_p1": 1, "roi_p2": 2, "roi_p3": 3, } conf = deepcopy(default_conf) conf.update({'config': 'config.json.example'}) conf.update({'epochs': 1}) conf.update({'timerange': None}) conf.update({'spaces': 'all'}) mocker.patch('freqtrade.optimize.hyperopt.load_data', MagicMock()) mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value=fmin_result) mocker.patch('freqtrade.optimize.hyperopt.hyperopt_optimize_conf', return_value=conf) StrategyResolver({'strategy': 'DefaultStrategy'}) hyperopt = Hyperopt(conf) hyperopt.trials = create_trials(mocker) hyperopt.tickerdata_to_dataframe = MagicMock() hyperopt.start() exists = [ 'Best parameters:', '"adx": {\n "enabled": true,\n "value": 15.0\n },', '"fastd": {\n "enabled": true,\n "value": 40.0\n },', '"green_candle": {\n "enabled": true\n },', '"macd_below_zero": {\n "enabled": false\n },', '"mfi": {\n "enabled": false\n },', '"over_sar": {\n "enabled": false\n },', '"roi_p1": 1.0,', '"roi_p2": 2.0,', '"roi_p3": 3.0,', '"roi_t1": 1.0,', '"roi_t2": 2.0,', '"roi_t3": 3.0,', '"rsi": {\n "enabled": true,\n "value": 37.0\n },', '"stoploss": -0.1,', '"trigger": {\n "type": "faststoch10"\n },', '"uptrend_long_ema": {\n "enabled": true\n },', '"uptrend_short_ema": {\n "enabled": false\n },', '"uptrend_sma": {\n "enabled": false\n }', 'ROI table:\n{0: 6.0, 3.0: 3.0, 5.0: 1.0, 6.0: 0}', 'Best Result:\nfoo' ] for line in exists: assert line in caplog.text
# pragma pylint: disable=missing-docstring,W0212,C0103 import json import os from copy import deepcopy from unittest.mock import MagicMock import pandas as pd from freqtrade.optimize.__init__ import load_tickerdata_file from freqtrade.optimize.hyperopt import Hyperopt, start from freqtrade.strategy.resolver import StrategyResolver from freqtrade.tests.conftest import default_conf, log_has from freqtrade.tests.optimize.test_backtesting import get_args # Avoid to reinit the same object again and again _HYPEROPT = Hyperopt(default_conf()) # Functions for recurrent object patching def create_trials(mocker) -> None: """ When creating trials, mock the hyperopt Trials so that *by default* - we don't create any pickle'd files in the filesystem - we might have a pickle'd file so make sure that we return false when looking for it """ _HYPEROPT.trials_file = os.path.join('freqtrade', 'tests', 'optimize', 'ut_trials.pickle') mocker.patch('freqtrade.optimize.hyperopt.os.path.exists', return_value=False)
def init_hyperopt(default_conf, mocker): global _HYPEROPT_INITIALIZED, _HYPEROPT if not _HYPEROPT_INITIALIZED: patch_exchange(mocker) _HYPEROPT = Hyperopt(default_conf) _HYPEROPT_INITIALIZED = True
def start_hyperopt_list(args: Dict[str, Any]) -> None: """ List hyperopt epochs previously evaluated """ from freqtrade.optimize.hyperopt import Hyperopt config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) print_colorized = config.get('print_colorized', False) print_json = config.get('print_json', False) export_csv = config.get('export_csv', None) no_details = config.get('hyperopt_list_no_details', False) no_header = False filteroptions = { 'only_best': config.get('hyperopt_list_best', False), 'only_profitable': config.get('hyperopt_list_profitable', False), 'filter_min_trades': config.get('hyperopt_list_min_trades', 0), 'filter_max_trades': config.get('hyperopt_list_max_trades', 0), 'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', None), 'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', None), 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', None), 'filter_max_avg_profit': config.get('hyperopt_list_max_avg_profit', None), 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', None), 'filter_max_total_profit': config.get('hyperopt_list_max_total_profit', None) } trials_file = (config['user_data_dir'] / 'hyperopt_results' / 'hyperopt_results.pickle') # Previous evaluations trials = Hyperopt.load_previous_results(trials_file) total_epochs = len(trials) trials = _hyperopt_filter_trials(trials, filteroptions) if print_colorized: colorama_init(autoreset=True) if not export_csv: try: print( Hyperopt.get_result_table(config, trials, total_epochs, not filteroptions['only_best'], print_colorized, 0)) except KeyboardInterrupt: print('User interrupted..') if trials and not no_details: sorted_trials = sorted(trials, key=itemgetter('loss')) results = sorted_trials[0] Hyperopt.print_epoch_details(results, total_epochs, print_json, no_header) if trials and export_csv: Hyperopt.export_csv_file(config, trials, total_epochs, not filteroptions['only_best'], export_csv)
def start_hyperopt_show(args: Dict[str, Any]) -> None: """ Show details of a hyperopt epoch previously evaluated """ from freqtrade.optimize.hyperopt import Hyperopt config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) print_json = config.get('print_json', False) no_header = config.get('hyperopt_show_no_header', False) trials_file = (config['user_data_dir'] / 'hyperopt_results' / 'hyperopt_results.pickle') n = config.get('hyperopt_show_index', -1) filteroptions = { 'only_best': config.get('hyperopt_list_best', False), 'only_profitable': config.get('hyperopt_list_profitable', False), 'filter_min_trades': config.get('hyperopt_list_min_trades', 0), 'filter_max_trades': config.get('hyperopt_list_max_trades', 0), 'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', None), 'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', None), 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', None), 'filter_max_avg_profit': config.get('hyperopt_list_max_avg_profit', None), 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', None), 'filter_max_total_profit': config.get('hyperopt_list_max_total_profit', None) } # Previous evaluations trials = Hyperopt.load_previous_results(trials_file) total_epochs = len(trials) trials = _hyperopt_filter_trials(trials, filteroptions) trials_epochs = len(trials) if n > trials_epochs: raise OperationalException( f"The index of the epoch to show should be less than {trials_epochs + 1}." ) if n < -trials_epochs: raise OperationalException( f"The index of the epoch to show should be greater than {-trials_epochs - 1}." ) # Translate epoch index from human-readable format to pythonic if n > 0: n -= 1 if trials: val = trials[n] Hyperopt.print_epoch_details(val, total_epochs, print_json, no_header, header_str="Epoch details")
def test_generate_optimizer(mocker, default_conf) -> None: """ Test Hyperopt.generate_optimizer() function """ conf = deepcopy(default_conf) conf.update({'config': 'config.json.example'}) conf.update({'timerange': None}) conf.update({'spaces': 'all'}) trades = [('BTC_POWR', 0.023117, 0.000233, 100)] labels = ['currency', 'profit_percent', 'profit_BTC', 'duration'] backtest_result = pd.DataFrame.from_records(trades, columns=labels) mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.backtest', MagicMock(return_value=backtest_result)) optimizer_param = { 'adx': { 'enabled': False }, 'fastd': { 'enabled': True, 'value': 35.0 }, 'green_candle': { 'enabled': True }, 'macd_below_zero': { 'enabled': True }, 'mfi': { 'enabled': False }, 'over_sar': { 'enabled': False }, 'roi_p1': 0.01, 'roi_p2': 0.01, 'roi_p3': 0.1, 'roi_t1': 60.0, 'roi_t2': 30.0, 'roi_t3': 20.0, 'rsi': { 'enabled': False }, 'stoploss': -0.4, 'trigger': { 'type': 'macd_cross_signal' }, 'uptrend_long_ema': { 'enabled': False }, 'uptrend_short_ema': { 'enabled': True }, 'uptrend_sma': { 'enabled': True } } response_expected = { 'loss': 1.9840569076926293, 'result': ' 1 trades. Avg profit 2.31%. Total profit 0.00023300 BTC ' '(0.0231Σ%). Avg duration 100.0 mins.', 'status': 'ok' } hyperopt = Hyperopt(conf) generate_optimizer_value = hyperopt.generate_optimizer(optimizer_param) assert generate_optimizer_value == response_expected
def test_generate_optimizer(mocker, hyperopt_conf) -> None: hyperopt_conf.update({ 'spaces': 'all', 'hyperopt_min_trades': 1, }) backtest_result = { 'results': pd.DataFrame({ "pair": ["UNITTEST/BTC", "UNITTEST/BTC", "UNITTEST/BTC", "UNITTEST/BTC"], "profit_ratio": [0.003312, 0.010801, 0.013803, 0.002780], "profit_abs": [0.000003, 0.000011, 0.000014, 0.000003], "open_date": [ Arrow(2017, 11, 14, 19, 32, 00).datetime, Arrow(2017, 11, 14, 21, 36, 00).datetime, Arrow(2017, 11, 14, 22, 12, 00).datetime, Arrow(2017, 11, 14, 22, 44, 00).datetime ], "close_date": [ Arrow(2017, 11, 14, 21, 35, 00).datetime, Arrow(2017, 11, 14, 22, 10, 00).datetime, Arrow(2017, 11, 14, 22, 43, 00).datetime, Arrow(2017, 11, 14, 22, 58, 00).datetime ], "open_rate": [0.002543, 0.003003, 0.003089, 0.003214], "close_rate": [0.002546, 0.003014, 0.003103, 0.003217], "trade_duration": [123, 34, 31, 14], "is_open": [False, False, False, True], "stake_amount": [0.01, 0.01, 0.01, 0.01], "sell_reason": [ SellType.ROI, SellType.STOP_LOSS, SellType.ROI, SellType.FORCE_SELL ] }), 'config': hyperopt_conf, 'locks': [], 'final_balance': 1000, } mocker.patch('freqtrade.optimize.hyperopt.Backtesting.backtest', return_value=backtest_result) mocker.patch('freqtrade.optimize.hyperopt.get_timerange', return_value=(Arrow(2017, 12, 10), Arrow(2017, 12, 13))) patch_exchange(mocker) mocker.patch('freqtrade.optimize.hyperopt.load', return_value={'XRP/BTC': None}) optimizer_param = { 'adx-value': 0, 'fastd-value': 35, 'mfi-value': 0, 'rsi-value': 0, 'adx-enabled': False, 'fastd-enabled': True, 'mfi-enabled': False, 'rsi-enabled': False, 'trigger': 'macd_cross_signal', 'sell-adx-value': 0, 'sell-fastd-value': 75, 'sell-mfi-value': 0, 'sell-rsi-value': 0, 'sell-adx-enabled': False, 'sell-fastd-enabled': True, 'sell-mfi-enabled': False, 'sell-rsi-enabled': False, 'sell-trigger': 'macd_cross_signal', 'roi_t1': 60.0, 'roi_t2': 30.0, 'roi_t3': 20.0, 'roi_p1': 0.01, 'roi_p2': 0.01, 'roi_p3': 0.1, 'stoploss': -0.4, 'trailing_stop': True, 'trailing_stop_positive': 0.02, 'trailing_stop_positive_offset_p1': 0.05, 'trailing_only_offset_is_reached': False, } response_expected = { 'loss': 1.9147239021396234, 'results_explanation': (' 4 trades. 4/0/0 Wins/Draws/Losses. ' 'Avg profit 0.77%. Median profit 0.71%. Total profit ' '0.00003100 BTC ( 0.00\N{GREEK CAPITAL LETTER SIGMA}%). ' 'Avg duration 0:50:00 min.').encode(locale.getpreferredencoding(), 'replace').decode('utf-8'), 'params_details': { 'buy': { 'adx-enabled': False, 'adx-value': 0, 'fastd-enabled': True, 'fastd-value': 35, 'mfi-enabled': False, 'mfi-value': 0, 'rsi-enabled': False, 'rsi-value': 0, 'trigger': 'macd_cross_signal' }, 'roi': { 0: 0.12000000000000001, 20.0: 0.02, 50.0: 0.01, 110.0: 0 }, 'sell': { 'sell-adx-enabled': False, 'sell-adx-value': 0, 'sell-fastd-enabled': True, 'sell-fastd-value': 75, 'sell-mfi-enabled': False, 'sell-mfi-value': 0, 'sell-rsi-enabled': False, 'sell-rsi-value': 0, 'sell-trigger': 'macd_cross_signal' }, 'stoploss': { 'stoploss': -0.4 }, 'trailing': { 'trailing_only_offset_is_reached': False, 'trailing_stop': True, 'trailing_stop_positive': 0.02, 'trailing_stop_positive_offset': 0.07 } }, 'params_dict': optimizer_param, 'params_not_optimized': { 'buy': {}, 'sell': {} }, 'results_metrics': ANY, 'total_profit': 3.1e-08 } hyperopt = Hyperopt(hyperopt_conf) hyperopt.min_date = Arrow(2017, 12, 10) hyperopt.max_date = Arrow(2017, 12, 13) hyperopt.init_spaces() hyperopt.dimensions = hyperopt.dimensions generate_optimizer_value = hyperopt.generate_optimizer( list(optimizer_param.values())) assert generate_optimizer_value == response_expected
def hyperopt(default_conf, mocker): default_conf.update({'spaces': ['all']}) patch_exchange(mocker) return Hyperopt(default_conf)
def hyperopt(default_conf, mocker): patch_exchange(mocker) return Hyperopt(default_conf)
def start_hyperopt_list(args: Dict[str, Any]) -> None: """ List hyperopt epochs previously evaluated """ from freqtrade.optimize.hyperopt import Hyperopt config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) print_colorized = config.get('print_colorized', False) print_json = config.get('print_json', False) no_details = config.get('hyperopt_list_no_details', False) no_header = False filteroptions = { 'only_best': config.get('hyperopt_list_best', False), 'only_profitable': config.get('hyperopt_list_profitable', False), 'filter_min_trades': config.get('hyperopt_list_min_trades', 0), 'filter_max_trades': config.get('hyperopt_list_max_trades', 0), 'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', None), 'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', None), 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', None), 'filter_max_avg_profit': config.get('hyperopt_list_max_avg_profit', None), 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', None), 'filter_max_total_profit': config.get('hyperopt_list_max_total_profit', None) } trials_file = (config['user_data_dir'] / 'hyperopt_results' / 'hyperopt_results.pickle') # Previous evaluations trials = Hyperopt.load_previous_results(trials_file) total_epochs = len(trials) trials = _hyperopt_filter_trials(trials, filteroptions) # TODO: fetch the interval for epochs to print from the cli option epoch_start, epoch_stop = 0, None if print_colorized: colorama_init(autoreset=True) try: # Human-friendly indexes used here (starting from 1) for val in trials[epoch_start:epoch_stop]: Hyperopt.print_results_explanation(val, total_epochs, not filteroptions['only_best'], print_colorized) except KeyboardInterrupt: print('User interrupted..') if trials and not no_details: sorted_trials = sorted(trials, key=itemgetter('loss')) results = sorted_trials[0] Hyperopt.print_epoch_details(results, total_epochs, print_json, no_header)