diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 574a669f6..428a5cddd 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -17,7 +17,6 @@ import rapidjson from joblib import Parallel, cpu_count, delayed, dump, load, wrap_non_picklable_objects from joblib.externals import cloudpickle from pandas import DataFrame -from rich.align import Align from rich.console import Console from freqtrade.constants import DATETIME_PRINT_FORMAT, FTHYPT_FILEVERSION, LAST_BT_RESULT_FN, Config @@ -80,7 +79,7 @@ class Hyperopt: self.max_open_trades_space: List[Dimension] = [] self.dimensions: List[Dimension] = [] - self._hyper_out: HyperoptOutput = HyperoptOutput() + self._hyper_out: HyperoptOutput = HyperoptOutput(streaming=True) self.config = config self.min_date: datetime @@ -635,7 +634,7 @@ class Hyperopt: # Define progressbar with get_progress_tracker( console=console, - cust_objs=[Align.center(self._hyper_out.table)], + cust_callables=[self._hyper_out], ) as pbar: task = pbar.add_task("Epochs", total=self.total_epochs) diff --git a/freqtrade/optimize/hyperopt_output.py b/freqtrade/optimize/hyperopt_output.py index 72e049745..eb6e2c509 100644 --- a/freqtrade/optimize/hyperopt_output.py +++ b/freqtrade/optimize/hyperopt_output.py @@ -1,6 +1,8 @@ import sys -from typing import List, Optional, Union +from os import get_terminal_size +from typing import Any, List, Optional +from rich.align import Align from rich.console import Console from rich.table import Table from rich.text import Text @@ -11,7 +13,16 @@ from freqtrade.util import fmt_coin class HyperoptOutput: - def __init__(self): + def __init__(self, streaming=False) -> None: + self._results: List[Any] = [] + self._streaming = streaming + self.__init_table() + + def __call__(self, *args: Any, **kwds: Any) -> Any: + return Align.center(self.table) + + def __init_table(self) -> None: + """Initialize table""" self.table = Table( title="Hyperopt results", ) @@ -26,17 +37,6 @@ class HyperoptOutput: self.table.add_column("Objective", justify="right") self.table.add_column("Max Drawdown (Acct)", justify="right") - def _add_row(self, data: List[Union[str, Text]]): - """Add single row""" - row_to_add: List[Union[str, Text]] = [r if isinstance(r, Text) else str(r) for r in data] - - self.table.add_row(*row_to_add) - - def _add_rows(self, data: List[List[Union[str, Text]]]): - """add multiple rows""" - for row in data: - self._add_row(row) - def print(self, console: Optional[Console] = None, *, print_colorized=True): if not console: console = Console( @@ -55,8 +55,19 @@ class HyperoptOutput: ) -> None: """Format one or multiple rows and add them""" stake_currency = config["stake_currency"] + self._results.extend(results) - for r in results: + max_rows: Optional[int] = None + + if self._streaming: + ts = get_terminal_size()[1] + # Get terminal size. + # Account for header, borders, and for the progress bar. + # This assumes that lines don't wrap. + max_rows: Optional[int] = -(ts - 6) if self._streaming else None + + self.__init_table() + for r in self._results[max_rows:]: self.table.add_row( *[ # "Best": diff --git a/freqtrade/util/rich_progress.py b/freqtrade/util/rich_progress.py index afa26683e..f4f993f7e 100644 --- a/freqtrade/util/rich_progress.py +++ b/freqtrade/util/rich_progress.py @@ -1,14 +1,18 @@ -from typing import Union +from typing import Callable, List, Union from rich.console import ConsoleRenderable, Group, RichCast from rich.progress import Progress class CustomProgress(Progress): - def __init__(self, *args, cust_objs=[], **kwargs) -> None: + def __init__(self, *args, cust_objs=[], cust_callables: List[Callable] = [], **kwargs) -> None: self._cust_objs = cust_objs + self._cust_callables = cust_callables super().__init__(*args, **kwargs) def get_renderable(self) -> Union[ConsoleRenderable, RichCast, str]: - renderable = Group(*self._cust_objs, *self.get_renderables()) + objs = [obj for obj in self._cust_objs] + for cust_call in self._cust_callables: + objs.append(cust_call()) + renderable = Group(*objs, *self.get_renderables()) return renderable