diff --git a/freqtrade/data/entryexitanalysis.py b/freqtrade/data/entryexitanalysis.py index 9d936d295..3981423f7 100644 --- a/freqtrade/data/entryexitanalysis.py +++ b/freqtrade/data/entryexitanalysis.py @@ -14,6 +14,7 @@ from freqtrade.data.btanalysis import ( load_backtest_stats, ) from freqtrade.exceptions import OperationalException +from freqtrade.util import print_df_rich_table logger = logging.getLogger(__name__) @@ -307,7 +308,7 @@ def _print_table( if name is not None: print(name) - print(tabulate(data, headers="keys", tablefmt="psql", showindex=show_index)) + print_df_rich_table(data, data.keys(), show_index=show_index) def process_entry_exit_reasons(config: Config): diff --git a/freqtrade/util/__init__.py b/freqtrade/util/__init__.py index f478829e6..5052e17dd 100644 --- a/freqtrade/util/__init__.py +++ b/freqtrade/util/__init__.py @@ -15,7 +15,7 @@ from freqtrade.util.formatters import decimals_per_coin, fmt_coin, round_value from freqtrade.util.ft_precise import FtPrecise from freqtrade.util.measure_time import MeasureTime from freqtrade.util.periodic_cache import PeriodicCache -from freqtrade.util.rich_tables import print_rich_table +from freqtrade.util.rich_tables import print_df_rich_table, print_rich_table from freqtrade.util.template_renderer import render_template, render_template_with_fallback # noqa @@ -38,4 +38,5 @@ __all__ = [ "fmt_coin", "MeasureTime", "print_rich_table", + "print_df_rich_table", ] diff --git a/freqtrade/util/rich_tables.py b/freqtrade/util/rich_tables.py index d34162d66..63715b70e 100644 --- a/freqtrade/util/rich_tables.py +++ b/freqtrade/util/rich_tables.py @@ -1,6 +1,7 @@ import sys from typing import Any, Dict, Optional, Sequence, Union +from pandas import DataFrame from rich.console import Console from rich.table import Table from rich.text import Text @@ -31,3 +32,37 @@ def print_rich_table( width=200 if "pytest" in sys.modules else None, ) console.print(table) + + +def _format_value(value: Any, *, floatfmt: str) -> str: + if isinstance(value, float): + return f"{value:{floatfmt}}" + return str(value) + + +def print_df_rich_table( + tabular_data: DataFrame, + headers: Sequence[str], + summary: Optional[str] = None, + *, + show_index=False, + index_name: Optional[str] = None, + table_kwargs: Optional[Dict[str, Any]] = None, +) -> None: + table = Table(title=summary, **(table_kwargs or {})) + + if show_index: + index_name = str(index_name) if index_name else tabular_data.index.name + table.add_column(index_name) + + for header in headers: + table.add_column(header, justify="right") + + for value_list in tabular_data.itertuples(index=show_index): + row = [_format_value(x, floatfmt=".3f") for x in value_list] + table.add_row(*row) + + console = Console( + width=200 if "pytest" in sys.modules else None, + ) + console.print(table) diff --git a/tests/data/test_entryexitanalysis.py b/tests/data/test_entryexitanalysis.py index 1a5309190..e7909c339 100644 --- a/tests/data/test_entryexitanalysis.py +++ b/tests/data/test_entryexitanalysis.py @@ -154,10 +154,10 @@ def test_backtest_analysis_nomock(default_conf, mocker, caplog, testdatadir, use assert "-3.5" in captured.out assert "50" in captured.out assert "0" in captured.out - assert "0.01616" in captured.out + assert "0.016" in captured.out assert "34.049" in captured.out - assert "0.104411" in captured.out - assert "52.8292" in captured.out + assert "0.104" in captured.out + assert "52.829" in captured.out # test group 1 args = get_args(base_args + ["--analysis-groups", "1"])