diff --git a/freqtrade/commands/analyze_commands.py b/freqtrade/commands/analyze_commands.py index 56330bed3..2fa13f683 100755 --- a/freqtrade/commands/analyze_commands.py +++ b/freqtrade/commands/analyze_commands.py @@ -56,7 +56,6 @@ def start_analysis_entries_exits(args: Dict[str, Any]) -> None: process_entry_exit_reasons(Path(config['user_data_dir'], 'backtest_results'), config['exchange']['pair_whitelist'], - config['strategy'], config['analysis_groups'], config['enter_reason_list'], config['exit_reason_list'], diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 679193e49..d5831a2ac 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -101,8 +101,8 @@ ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperop "print_json", "hyperoptexportfilename", "hyperopt_show_no_header", "disableparamexport", "backtest_breakdown"] -ARGS_ANALYZE_ENTRIES_EXITS = ["analysis-groups", "enter-reason-list", - "exit-reason-list", "indicator-list"] +ARGS_ANALYZE_ENTRIES_EXITS = ["analysis_groups", "enter_reason_list", + "exit_reason_list", "indicator_list"] NO_CONF_REQURIED = ["convert-data", "convert-trade-data", "download-data", "list-timeframes", "list-markets", "list-pairs", "list-strategies", "list-data", @@ -421,7 +421,8 @@ class Arguments: self._build_args(optionlist=ARGS_WEBSERVER, parser=webserver_cmd) # Add backtesting analysis subcommand - analysis_cmd = subparsers.add_parser('analysis', help='Backtest Analysis module.', + analysis_cmd = subparsers.add_parser('backtesting-analysis', + help='Backtest Analysis module.', parents=[_common_parser, _strategy_parser]) analysis_cmd.set_defaults(func=start_analysis_entries_exits) self._build_args(optionlist=ARGS_ANALYZE_ENTRIES_EXITS, parser=analysis_cmd) diff --git a/freqtrade/data/entryexitanalysis.py b/freqtrade/data/entryexitanalysis.py index 1ee6eea42..15ac6ba09 100755 --- a/freqtrade/data/entryexitanalysis.py +++ b/freqtrade/data/entryexitanalysis.py @@ -15,14 +15,13 @@ logger = logging.getLogger(__name__) def _load_signal_candles(backtest_dir: Path): - if backtest_dir.is_dir(): scpf = Path(backtest_dir, Path(get_latest_backtest_filename(backtest_dir)).stem + "_signals.pkl" ) else: scpf = Path(Path(get_latest_backtest_filename(backtest_dir)).stem + "_signals.pkl") - print(scpf) + try: scp = open(scpf, "rb") signal_candles = joblib.load(scp) @@ -154,7 +153,6 @@ def _do_group_table_output(bigdf, glist): def _print_results(analysed_trades, stratname, analysis_groups, enter_reason_list, exit_reason_list, indicator_list, columns=None): - if columns is None: columns = ['pair', 'open_date', 'close_date', 'profit_abs', 'enter_reason', 'exit_reason'] @@ -209,26 +207,25 @@ def _print_table(df, sortcols=None, show_index=False): def process_entry_exit_reasons(backtest_dir: Path, pairlist: List[str], - strategy_name: str, analysis_groups: Optional[str] = "0,1,2", enter_reason_list: Optional[str] = "all", exit_reason_list: Optional[str] = "all", indicator_list: Optional[str] = None): - try: - bt_stats = load_backtest_stats(backtest_dir) - logger.info(bt_stats) - # strategy_name = bt_stats['something'] - trades = load_backtest_data(backtest_dir, strategy_name) + backtest_stats = load_backtest_stats(backtest_dir) + for strategy_name, results in backtest_stats['strategy'].items(): + trades = load_backtest_data(backtest_dir, strategy_name) + + if not trades.empty: + signal_candles = _load_signal_candles(backtest_dir) + analysed_trades_dict = _process_candles_and_indicators(pairlist, strategy_name, + trades, signal_candles) + _print_results(analysed_trades_dict, + strategy_name, + analysis_groups, + enter_reason_list, + exit_reason_list, + indicator_list) + except ValueError as e: raise OperationalException(e) from e - if not trades.empty: - signal_candles = _load_signal_candles(backtest_dir) - analysed_trades_dict = _process_candles_and_indicators(pairlist, strategy_name, - trades, signal_candles) - _print_results(analysed_trades_dict, - strategy_name, - analysis_groups, - enter_reason_list, - exit_reason_list, - indicator_list) diff --git a/tests/data/test_entryexitanalysis.py b/tests/data/test_entryexitanalysis.py index 90da80ce9..eadf79179 100755 --- a/tests/data/test_entryexitanalysis.py +++ b/tests/data/test_entryexitanalysis.py @@ -24,10 +24,6 @@ def test_backtest_analysis_nomock(default_conf, mocker, caplog, testdatadir, tmp "exit_profit_only": False, "exit_profit_offset": 0.0, "ignore_roi_if_entry_signal": False, - 'analysis-groups': "0", - 'enter-reason-list': "all", - 'exit-reason-list': "all", - 'indicator-list': "rsi" }) patch_exchange(mocker) result1 = pd.DataFrame({'pair': ['ETH/BTC', 'LTC/BTC'], @@ -89,8 +85,15 @@ def test_backtest_analysis_nomock(default_conf, mocker, caplog, testdatadir, tmp assert 'EXIT REASON STATS' in captured.out assert 'LEFT OPEN TRADES REPORT' in captured.out + default_conf.update({ + 'analysis_groups': "0", + 'enter_reason_list': "all", + 'exit_reason_list': "all", + 'indicator_list': "rsi" + }) + args = [ - 'analysis', + 'backtesting-analysis', '--config', 'config.json', '--datadir', str(testdatadir), '--user-data-dir', str(tmpdir),