From c475729c13c22b404c469dec6dbdb9256a312fb8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 9 Jan 2020 06:52:34 +0100 Subject: [PATCH] Extract edge reporting to optimize_reports --- freqtrade/optimize/backtesting.py | 2 +- freqtrade/optimize/edge_cli.py | 32 ++----------------- ...acktest_reports.py => optimize_reports.py} | 26 +++++++++++++++ tests/optimize/test_backtest_reports.py | 16 ++++++++-- tests/optimize/test_edge_cli.py | 14 -------- 5 files changed, 44 insertions(+), 46 deletions(-) rename freqtrade/optimize/{backtest_reports.py => optimize_reports.py} (83%) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index ae3fbed0a..18cc27ff4 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -18,7 +18,7 @@ from freqtrade.data.dataprovider import DataProvider from freqtrade.exceptions import OperationalException from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds from freqtrade.misc import file_dump_json -from freqtrade.optimize.backtest_reports import ( +from freqtrade.optimize.optimize_reports import ( generate_text_table, generate_text_table_sell_reason, generate_text_table_strategy) from freqtrade.persistence import Trade diff --git a/freqtrade/optimize/edge_cli.py b/freqtrade/optimize/edge_cli.py index 4944f1dbb..be19688d8 100644 --- a/freqtrade/optimize/edge_cli.py +++ b/freqtrade/optimize/edge_cli.py @@ -6,13 +6,12 @@ This module contains the edge backtesting interface import logging from typing import Any, Dict -from tabulate import tabulate - from freqtrade import constants from freqtrade.configuration import (TimeRange, remove_credentials, validate_config_consistency) from freqtrade.edge import Edge -from freqtrade.resolvers import StrategyResolver, ExchangeResolver +from freqtrade.optimize.optimize_reports import generate_edge_table +from freqtrade.resolvers import ExchangeResolver, StrategyResolver logger = logging.getLogger(__name__) @@ -44,33 +43,8 @@ class EdgeCli: self.edge._timerange = TimeRange.parse_timerange(None if self.config.get( 'timerange') is None else str(self.config.get('timerange'))) - def _generate_edge_table(self, results: dict) -> str: - - floatfmt = ('s', '.10g', '.2f', '.2f', '.2f', '.2f', 'd', '.d') - tabular_data = [] - headers = ['pair', 'stoploss', 'win rate', 'risk reward ratio', - 'required risk reward', 'expectancy', 'total number of trades', - 'average duration (min)'] - - for result in results.items(): - if result[1].nb_trades > 0: - tabular_data.append([ - result[0], - result[1].stoploss, - result[1].winrate, - result[1].risk_reward_ratio, - result[1].required_risk_reward, - result[1].expectancy, - result[1].nb_trades, - round(result[1].avg_trade_duration) - ]) - - # Ignore type as floatfmt does allow tuples but mypy does not know that - return tabulate(tabular_data, headers=headers, - floatfmt=floatfmt, tablefmt="pipe") # type: ignore - def start(self) -> None: result = self.edge.calculate() if result: print('') # blank line for readability - print(self._generate_edge_table(self.edge._cached_pairs)) + print(generate_edge_table(self.edge._cached_pairs)) diff --git a/freqtrade/optimize/backtest_reports.py b/freqtrade/optimize/optimize_reports.py similarity index 83% rename from freqtrade/optimize/backtest_reports.py rename to freqtrade/optimize/optimize_reports.py index 555250760..ffc8c53d4 100644 --- a/freqtrade/optimize/backtest_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -107,3 +107,29 @@ def generate_text_table_strategy(stake_currency: str, max_open_trades: str, # Ignore type as floatfmt does allow tuples but mypy does not know that return tabulate(tabular_data, headers=headers, floatfmt=floatfmt, tablefmt="pipe") # type: ignore + + +def generate_edge_table(results: dict) -> str: + + floatfmt = ('s', '.10g', '.2f', '.2f', '.2f', '.2f', 'd', '.d') + tabular_data = [] + headers = ['pair', 'stoploss', 'win rate', 'risk reward ratio', + 'required risk reward', 'expectancy', 'total number of trades', + 'average duration (min)'] + + for result in results.items(): + if result[1].nb_trades > 0: + tabular_data.append([ + result[0], + result[1].stoploss, + result[1].winrate, + result[1].risk_reward_ratio, + result[1].required_risk_reward, + result[1].expectancy, + result[1].nb_trades, + round(result[1].avg_trade_duration) + ]) + + # Ignore type as floatfmt does allow tuples but mypy does not know that + return tabulate(tabular_data, headers=headers, + floatfmt=floatfmt, tablefmt="pipe") # type: ignore diff --git a/tests/optimize/test_backtest_reports.py b/tests/optimize/test_backtest_reports.py index 107389a42..518b50d0f 100644 --- a/tests/optimize/test_backtest_reports.py +++ b/tests/optimize/test_backtest_reports.py @@ -1,7 +1,8 @@ import pandas as pd -from freqtrade.optimize.backtest_reports import ( - generate_text_table, generate_text_table_sell_reason, +from freqtrade.edge import PairInfo +from freqtrade.optimize.optimize_reports import ( + generate_edge_table, generate_text_table, generate_text_table_sell_reason, generate_text_table_strategy) from freqtrade.strategy.interface import SellType @@ -94,3 +95,14 @@ def test_generate_text_table_strategy(default_conf, mocker): '| 1.30000000 | 45.00 | 0:20:00 | 3 | 0 |' ) assert generate_text_table_strategy('BTC', 2, all_results=results) == result_str + + +def test_generate_edge_table(edge_conf, mocker): + + results = {} + results['ETH/BTC'] = PairInfo(-0.01, 0.60, 2, 1, 3, 10, 60) + + assert generate_edge_table(results).count(':|') == 7 + assert generate_edge_table(results).count('| ETH/BTC |') == 1 + assert generate_edge_table(results).count( + '| risk reward ratio | required risk reward | expectancy |') == 1 diff --git a/tests/optimize/test_edge_cli.py b/tests/optimize/test_edge_cli.py index ddfa7156e..acc0d2d16 100644 --- a/tests/optimize/test_edge_cli.py +++ b/tests/optimize/test_edge_cli.py @@ -3,7 +3,6 @@ from unittest.mock import MagicMock -from freqtrade.edge import PairInfo from freqtrade.optimize import setup_configuration, start_edge from freqtrade.optimize.edge_cli import EdgeCli from freqtrade.state import RunMode @@ -106,16 +105,3 @@ def test_edge_init_fee(mocker, edge_conf) -> None: edge_cli = EdgeCli(edge_conf) assert edge_cli.edge.fee == 0.1234 assert fee_mock.call_count == 0 - - -def test_generate_edge_table(edge_conf, mocker): - patch_exchange(mocker) - edge_cli = EdgeCli(edge_conf) - - results = {} - results['ETH/BTC'] = PairInfo(-0.01, 0.60, 2, 1, 3, 10, 60) - - assert edge_cli._generate_edge_table(results).count(':|') == 7 - assert edge_cli._generate_edge_table(results).count('| ETH/BTC |') == 1 - assert edge_cli._generate_edge_table(results).count( - '| risk reward ratio | required risk reward | expectancy |') == 1