Extract edge reporting to optimize_reports

This commit is contained in:
Matthias 2020-01-09 06:52:34 +01:00
parent 989ab646a9
commit c475729c13
5 changed files with 44 additions and 46 deletions

View File

@ -18,7 +18,7 @@ from freqtrade.data.dataprovider import DataProvider
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds
from freqtrade.misc import file_dump_json 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, generate_text_table_sell_reason,
generate_text_table_strategy) generate_text_table_strategy)
from freqtrade.persistence import Trade from freqtrade.persistence import Trade

View File

@ -6,13 +6,12 @@ This module contains the edge backtesting interface
import logging import logging
from typing import Any, Dict from typing import Any, Dict
from tabulate import tabulate
from freqtrade import constants from freqtrade import constants
from freqtrade.configuration import (TimeRange, remove_credentials, from freqtrade.configuration import (TimeRange, remove_credentials,
validate_config_consistency) validate_config_consistency)
from freqtrade.edge import Edge 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__) logger = logging.getLogger(__name__)
@ -44,33 +43,8 @@ class EdgeCli:
self.edge._timerange = TimeRange.parse_timerange(None if self.config.get( self.edge._timerange = TimeRange.parse_timerange(None if self.config.get(
'timerange') is None else str(self.config.get('timerange'))) '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: def start(self) -> None:
result = self.edge.calculate() result = self.edge.calculate()
if result: if result:
print('') # blank line for readability print('') # blank line for readability
print(self._generate_edge_table(self.edge._cached_pairs)) print(generate_edge_table(self.edge._cached_pairs))

View File

@ -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 # Ignore type as floatfmt does allow tuples but mypy does not know that
return tabulate(tabular_data, headers=headers, return tabulate(tabular_data, headers=headers,
floatfmt=floatfmt, tablefmt="pipe") # type: ignore 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

View File

@ -1,7 +1,8 @@
import pandas as pd import pandas as pd
from freqtrade.optimize.backtest_reports import ( from freqtrade.edge import PairInfo
generate_text_table, generate_text_table_sell_reason, from freqtrade.optimize.optimize_reports import (
generate_edge_table, generate_text_table, generate_text_table_sell_reason,
generate_text_table_strategy) generate_text_table_strategy)
from freqtrade.strategy.interface import SellType 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 |' '| 1.30000000 | 45.00 | 0:20:00 | 3 | 0 |'
) )
assert generate_text_table_strategy('BTC', 2, all_results=results) == result_str 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

View File

@ -3,7 +3,6 @@
from unittest.mock import MagicMock from unittest.mock import MagicMock
from freqtrade.edge import PairInfo
from freqtrade.optimize import setup_configuration, start_edge from freqtrade.optimize import setup_configuration, start_edge
from freqtrade.optimize.edge_cli import EdgeCli from freqtrade.optimize.edge_cli import EdgeCli
from freqtrade.state import RunMode from freqtrade.state import RunMode
@ -106,16 +105,3 @@ def test_edge_init_fee(mocker, edge_conf) -> None:
edge_cli = EdgeCli(edge_conf) edge_cli = EdgeCli(edge_conf)
assert edge_cli.edge.fee == 0.1234 assert edge_cli.edge.fee == 0.1234
assert fee_mock.call_count == 0 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