From cbb0294cd2ad22d557b4a5a83ce7be760e2f0ce0 Mon Sep 17 00:00:00 2001 From: mrpabloyeah Date: Sun, 18 May 2025 13:02:47 +0200 Subject: [PATCH] Format duration to make results more readable --- .../optimize_reports/optimize_reports.py | 16 ++++++++-------- freqtrade/util/__init__.py | 9 ++++++++- freqtrade/util/formatters.py | 14 ++++++++++++++ 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/freqtrade/optimize/optimize_reports/optimize_reports.py b/freqtrade/optimize/optimize_reports/optimize_reports.py index a62a5144e..a220186ad 100644 --- a/freqtrade/optimize/optimize_reports/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports/optimize_reports.py @@ -23,7 +23,7 @@ from freqtrade.ft_types import ( BacktestResultType, get_BacktestResultType_default, ) -from freqtrade.util import decimals_per_coin, fmt_coin, get_dry_run_wallet +from freqtrade.util import decimals_per_coin, fmt_coin, format_duration, get_dry_run_wallet logger = logging.getLogger(__name__) @@ -383,19 +383,19 @@ def generate_trading_stats(results: DataFrame) -> dict[str, Any]: "losses": len(losing_trades), "draws": len(draw_trades), "winrate": len(winning_trades) / len(results) if len(results) else 0.0, - "holding_avg": holding_avg, + "holding_avg": format_duration(holding_avg), "holding_avg_s": holding_avg.total_seconds(), - "winner_holding_min": winner_holding_min, + "winner_holding_min": format_duration(winner_holding_min), "winner_holding_min_s": winner_holding_min.total_seconds(), - "winner_holding_max": winner_holding_max, + "winner_holding_max": format_duration(winner_holding_max), "winner_holding_max_s": winner_holding_max.total_seconds(), - "winner_holding_avg": winner_holding_avg, + "winner_holding_avg": format_duration(winner_holding_avg), "winner_holding_avg_s": winner_holding_avg.total_seconds(), - "loser_holding_min": loser_holding_min, + "loser_holding_min": format_duration(loser_holding_min), "loser_holding_min_s": loser_holding_min.total_seconds(), - "loser_holding_max": loser_holding_max, + "loser_holding_max": format_duration(loser_holding_max), "loser_holding_max_s": loser_holding_max.total_seconds(), - "loser_holding_avg": loser_holding_avg, + "loser_holding_avg": format_duration(loser_holding_avg), "loser_holding_avg_s": loser_holding_avg.total_seconds(), "max_consecutive_wins": winstreak, "max_consecutive_losses": loss_streak, diff --git a/freqtrade/util/__init__.py b/freqtrade/util/__init__.py index 5a4857eea..98fda93cd 100644 --- a/freqtrade/util/__init__.py +++ b/freqtrade/util/__init__.py @@ -13,7 +13,13 @@ from freqtrade.util.datetime_helpers import ( shorten_date, ) from freqtrade.util.dry_run_wallet import get_dry_run_wallet -from freqtrade.util.formatters import decimals_per_coin, fmt_coin, fmt_coin2, round_value +from freqtrade.util.formatters import ( + decimals_per_coin, + fmt_coin, + fmt_coin2, + format_duration, + round_value, +) from freqtrade.util.ft_precise import FtPrecise from freqtrade.util.measure_time import MeasureTime from freqtrade.util.periodic_cache import PeriodicCache @@ -44,6 +50,7 @@ __all__ = [ "shorten_date", "decimals_per_coin", "round_value", + "format_duration", "fmt_coin", "fmt_coin2", "MeasureTime", diff --git a/freqtrade/util/formatters.py b/freqtrade/util/formatters.py index 82ac1cf66..fa656f52b 100644 --- a/freqtrade/util/formatters.py +++ b/freqtrade/util/formatters.py @@ -1,3 +1,5 @@ +from datetime import timedelta + from freqtrade.constants import DECIMAL_PER_COIN_FALLBACK, DECIMALS_PER_COIN @@ -66,3 +68,15 @@ def fmt_coin2( val = f"{val} {coin}" return val + + +def format_duration(td: timedelta) -> str: + """ + Format a timedelta object to "XXd HH:MM" format + :param td: Timedelta object to format + :return: Formatted time string + """ + d = td.days + h, r = divmod(td.seconds, 3600) + m, s = divmod(r, 60) + return f"{d}d {h:02d}:{m:02d}"