diff --git a/freqtrade/optimize/optimize_reports/bt_output.py b/freqtrade/optimize/optimize_reports/bt_output.py index a96ba4584..338fe5ca5 100644 --- a/freqtrade/optimize/optimize_reports/bt_output.py +++ b/freqtrade/optimize/optimize_reports/bt_output.py @@ -194,6 +194,7 @@ def text_table_strategy(strategy_results, stake_currency: str, title: str): def text_table_add_metrics(strat_results: dict) -> None: + stake = strat_results["stake_currency"] if len(strat_results["trades"]) > 0: best_trade = max(strat_results["trades"], key=lambda x: x["profit_ratio"]) worst_trade = min(strat_results["trades"], key=lambda x: x["profit_ratio"]) @@ -202,23 +203,19 @@ def text_table_add_metrics(strat_results: dict) -> None: [ ("", ""), # Empty line to improve readability ( - "Long / Short", + "Long / Short trades", f"{strat_results.get('trade_count_long', 'total_trades')} / " f"{strat_results.get('trade_count_short', 0)}", ), - ("Total profit Long %", f"{strat_results['profit_total_long']:.2%}"), - ("Total profit Short %", f"{strat_results['profit_total_short']:.2%}"), ( - "Absolute profit Long", - fmt_coin( - strat_results["profit_total_long_abs"], strat_results["stake_currency"] - ), + "Long / Short profit %", + f"{strat_results['profit_total_long']:.2%} / " + f"{strat_results['profit_total_short']:.2%}", ), ( - "Absolute profit Short", - fmt_coin( - strat_results["profit_total_short_abs"], strat_results["stake_currency"] - ), + f"Long / Short profit {stake}", + f"{strat_results['profit_total_long_abs']:.{decimals_per_coin(stake)}f} / " + f"{strat_results['profit_total_short_abs']:.{decimals_per_coin(stake)}f}", ), ] if strat_results.get("trade_count_short", 0) > 0 @@ -231,27 +228,34 @@ def text_table_add_metrics(strat_results: dict) -> None: drawdown_metrics.append( ("Max % of account underwater", f"{strat_results['max_relative_drawdown']:.2%}") ) + drawdown_account = ( + strat_results["max_drawdown_account"] + if "max_drawdown_account" in strat_results + else strat_results["max_drawdown"] + ) drawdown_metrics.extend( [ ( - ("Absolute Drawdown (Account)", f"{strat_results['max_drawdown_account']:.2%}") - if "max_drawdown_account" in strat_results - else ("Drawdown", f"{strat_results['max_drawdown']:.2%}") + "Absolute drawdown", + f"{fmt_coin(strat_results['max_drawdown_abs'], stake)} " + f"({drawdown_account:.2%})", ), ( - "Absolute Drawdown", - fmt_coin(strat_results["max_drawdown_abs"], strat_results["stake_currency"]), + "Drawdown duration", + strat_results["drawdown_duration"] + if "drawdown_duration" in strat_results + else "N/A", ), ( - "Drawdown high", - fmt_coin(strat_results["max_drawdown_high"], strat_results["stake_currency"]), + "Profit at drawdown start", + fmt_coin(strat_results["max_drawdown_high"], stake), ), ( - "Drawdown low", - fmt_coin(strat_results["max_drawdown_low"], strat_results["stake_currency"]), + "Profit at drawdown end", + fmt_coin(strat_results["max_drawdown_low"], stake), ), - ("Drawdown Start", strat_results["drawdown_start"]), - ("Drawdown End", strat_results["drawdown_end"]), + ("Drawdown start", strat_results["drawdown_start"]), + ("Drawdown end", strat_results["drawdown_end"]), ] ) @@ -299,15 +303,15 @@ def text_table_add_metrics(strat_results: dict) -> None: ), ( "Starting balance", - fmt_coin(strat_results["starting_balance"], strat_results["stake_currency"]), + fmt_coin(strat_results["starting_balance"], stake), ), ( "Final balance", - fmt_coin(strat_results["final_balance"], strat_results["stake_currency"]), + fmt_coin(strat_results["final_balance"], stake), ), ( "Absolute profit ", - fmt_coin(strat_results["profit_total_abs"], strat_results["stake_currency"]), + fmt_coin(strat_results["profit_total_abs"], stake), ), ("Total profit %", f"{strat_results['profit_total']:.2%}"), ("CAGR %", f"{strat_results['cagr']:.2%}" if "cagr" in strat_results else "N/A"), @@ -335,16 +339,16 @@ def text_table_add_metrics(strat_results: dict) -> None: "Avg. daily profit", fmt_coin( (strat_results["profit_total_abs"] / strat_results["backtest_days"]), - strat_results["stake_currency"], + stake, ), ), ( "Avg. stake amount", - fmt_coin(strat_results["avg_stake_amount"], strat_results["stake_currency"]), + fmt_coin(strat_results["avg_stake_amount"], stake), ), ( "Total trade volume", - fmt_coin(strat_results["total_volume"], strat_results["stake_currency"]), + fmt_coin(strat_results["total_volume"], stake), ), *short_metrics, ("", ""), # Empty line to improve readability @@ -362,11 +366,11 @@ def text_table_add_metrics(strat_results: dict) -> None: ("Worst trade", f"{worst_trade['pair']} {worst_trade['profit_ratio']:.2%}"), ( "Best day", - fmt_coin(strat_results["backtest_best_day_abs"], strat_results["stake_currency"]), + fmt_coin(strat_results["backtest_best_day_abs"], stake), ), ( "Worst day", - fmt_coin(strat_results["backtest_worst_day_abs"], strat_results["stake_currency"]), + fmt_coin(strat_results["backtest_worst_day_abs"], stake), ), ( "Days win/draw/lose", @@ -404,17 +408,17 @@ def text_table_add_metrics(strat_results: dict) -> None: ), *entry_adjustment_metrics, ("", ""), # Empty line to improve readability - ("Min balance", fmt_coin(strat_results["csum_min"], strat_results["stake_currency"])), - ("Max balance", fmt_coin(strat_results["csum_max"], strat_results["stake_currency"])), + ("Min balance", fmt_coin(strat_results["csum_min"], stake)), + ("Max balance", fmt_coin(strat_results["csum_max"], stake)), *drawdown_metrics, ("Market change", f"{strat_results['market_change']:.2%}"), ] print_rich_table(metrics, ["Metric", "Value"], summary="SUMMARY METRICS", justify="left") else: - start_balance = fmt_coin(strat_results["starting_balance"], strat_results["stake_currency"]) + start_balance = fmt_coin(strat_results["starting_balance"], stake) stake_amount = ( - fmt_coin(strat_results["stake_amount"], strat_results["stake_currency"]) + fmt_coin(strat_results["stake_amount"], stake) if strat_results["stake_amount"] != UNLIMITED_STAKE_AMOUNT else "unlimited" ) diff --git a/freqtrade/optimize/optimize_reports/optimize_reports.py b/freqtrade/optimize/optimize_reports/optimize_reports.py index c46f5af78..a53980fb3 100644 --- a/freqtrade/optimize/optimize_reports/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports/optimize_reports.py @@ -627,6 +627,7 @@ def generate_strategy_stats( underwater = calculate_max_drawdown( results, value_col="profit_abs", starting_balance=start_balance, relative=True ) + drawdown_duration = drawdown.low_date - drawdown.high_date strat_stats.update( { @@ -637,6 +638,8 @@ def generate_strategy_stats( "drawdown_start_ts": drawdown.high_date.timestamp() * 1000, "drawdown_end": drawdown.low_date.strftime(DATETIME_PRINT_FORMAT), "drawdown_end_ts": drawdown.low_date.timestamp() * 1000, + "drawdown_duration": drawdown_duration, + "drawdown_duration_s": drawdown_duration.total_seconds(), "max_drawdown_low": drawdown.low_value, "max_drawdown_high": drawdown.high_value, }