From 718efc828a993ad6dfe1ffe33cd8e2c4e2a83954 Mon Sep 17 00:00:00 2001 From: mrpabloyeah Date: Sat, 17 May 2025 14:22:25 +0200 Subject: [PATCH] Also add min trade duration and display the info horizontally --- .../optimize/optimize_reports/bt_output.py | 15 +++++-- .../optimize_reports/optimize_reports.py | 41 +++++++++++++++---- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/freqtrade/optimize/optimize_reports/bt_output.py b/freqtrade/optimize/optimize_reports/bt_output.py index 94dc966a5..c305a7b0e 100644 --- a/freqtrade/optimize/optimize_reports/bt_output.py +++ b/freqtrade/optimize/optimize_reports/bt_output.py @@ -370,9 +370,18 @@ def text_table_add_metrics(strat_results: dict) -> None: f"{strat_results['winning_days']} / " f"{strat_results['draw_days']} / {strat_results['losing_days']}", ), - ("Max trade duration", f"{strat_results['holding_max']}"), - ("Avg. Duration Winners", f"{strat_results['winner_holding_avg']}"), - ("Avg. Duration Loser", f"{strat_results['loser_holding_avg']}"), + ( + "Min/Max/Avg. Duration Winners", + f"{strat_results.get('winner_holding_min', 'N/A')} / " + f"{strat_results.get('winner_holding_max', 'N/A')} / " + f"{strat_results.get('winner_holding_avg', 'N/A')}", + ), + ( + "Min/Max/Avg. Duration Losers", + f"{strat_results.get('loser_holding_min', 'N/A')} / " + f"{strat_results.get('loser_holding_max', 'N/A')} / " + f"{strat_results.get('loser_holding_avg', 'N/A')}", + ), ( "Max Consecutive Wins / Loss", ( diff --git a/freqtrade/optimize/optimize_reports/optimize_reports.py b/freqtrade/optimize/optimize_reports/optimize_reports.py index f331c0709..f857342b3 100644 --- a/freqtrade/optimize/optimize_reports/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports/optimize_reports.py @@ -336,27 +336,44 @@ def generate_trading_stats(results: DataFrame) -> dict[str, Any]: } winning_trades = results.loc[results["profit_ratio"] > 0] + winning_duratios = winning_trades["trade_duration"] draw_trades = results.loc[results["profit_ratio"] == 0] losing_trades = results.loc[results["profit_ratio"] < 0] + losing_duratios = losing_trades["trade_duration"] holding_avg = ( timedelta(minutes=round(results["trade_duration"].mean())) if not results.empty else timedelta() ) - holding_max = ( - timedelta(minutes=round(results["trade_duration"].max())) - if not results.empty + winner_holding_min = ( + timedelta(minutes=round(winning_duratios[winning_duratios > 0].min())) + if not winning_duratios.empty + else timedelta() + ) + winner_holding_max = ( + timedelta(minutes=round(winning_duratios.max())) + if not winning_duratios.empty else timedelta() ) winner_holding_avg = ( - timedelta(minutes=round(winning_trades["trade_duration"].mean())) - if not winning_trades.empty + timedelta(minutes=round(winning_duratios.mean())) + if not winning_duratios.empty + else timedelta() + ) + loser_holding_min = ( + timedelta(minutes=round(losing_duratios[losing_duratios > 0].min())) + if not losing_duratios.empty + else timedelta() + ) + loser_holding_max = ( + timedelta(minutes=round(losing_duratios.max())) + if not losing_duratios.empty else timedelta() ) loser_holding_avg = ( - timedelta(minutes=round(losing_trades["trade_duration"].mean())) - if not losing_trades.empty + timedelta(minutes=round(losing_duratios.mean())) + if not losing_duratios.empty else timedelta() ) winstreak, loss_streak = calc_streak(results) @@ -368,10 +385,16 @@ def generate_trading_stats(results: DataFrame) -> dict[str, Any]: "winrate": len(winning_trades) / len(results) if len(results) else 0.0, "holding_avg": holding_avg, "holding_avg_s": holding_avg.total_seconds(), - "holding_max": holding_max, - "holding_max_s": holding_max.total_seconds(), + "winner_holding_min": winner_holding_min, + "winner_holding_min_s": winner_holding_min.total_seconds(), + "winner_holding_max": winner_holding_max, + "winner_holding_max_s": winner_holding_max.total_seconds(), "winner_holding_avg": winner_holding_avg, "winner_holding_avg_s": winner_holding_avg.total_seconds(), + "loser_holding_min": loser_holding_min, + "loser_holding_min_s": loser_holding_min.total_seconds(), + "loser_holding_max": loser_holding_max, + "loser_holding_max_s": loser_holding_max.total_seconds(), "loser_holding_avg": loser_holding_avg, "loser_holding_avg_s": loser_holding_avg.total_seconds(), "max_consecutive_wins": winstreak,