Extract generate_text_table_strategy to seperate module
This commit is contained in:
parent
caec345c0b
commit
904e1647e1
@ -64,3 +64,32 @@ def generate_text_table_sell_reason(data: Dict[str, Dict], results: DataFrame) -
|
|||||||
loss = len(results[(results['sell_reason'] == reason) & (results['profit_abs'] < 0)])
|
loss = len(results[(results['sell_reason'] == reason) & (results['profit_abs'] < 0)])
|
||||||
tabular_data.append([reason.value, count, profit, loss])
|
tabular_data.append([reason.value, count, profit, loss])
|
||||||
return tabulate(tabular_data, headers=headers, tablefmt="pipe")
|
return tabulate(tabular_data, headers=headers, tablefmt="pipe")
|
||||||
|
|
||||||
|
|
||||||
|
def generate_text_table_strategy(stake_currency: str, max_open_trades: str,
|
||||||
|
all_results: Dict) -> str:
|
||||||
|
"""
|
||||||
|
Generate summary table per strategy
|
||||||
|
"""
|
||||||
|
|
||||||
|
floatfmt = ('s', 'd', '.2f', '.2f', '.8f', '.2f', 'd', '.1f', '.1f')
|
||||||
|
tabular_data = []
|
||||||
|
headers = ['Strategy', 'buy count', 'avg profit %', 'cum profit %',
|
||||||
|
f'tot profit {stake_currency}', 'tot profit %', 'avg duration',
|
||||||
|
'profit', 'loss']
|
||||||
|
for strategy, results in all_results.items():
|
||||||
|
tabular_data.append([
|
||||||
|
strategy,
|
||||||
|
len(results.index),
|
||||||
|
results.profit_percent.mean() * 100.0,
|
||||||
|
results.profit_percent.sum() * 100.0,
|
||||||
|
results.profit_abs.sum(),
|
||||||
|
results.profit_percent.sum() * 100.0 / max_open_trades,
|
||||||
|
str(timedelta(
|
||||||
|
minutes=round(results.trade_duration.mean()))) if not results.empty else '0:00',
|
||||||
|
len(results[results.profit_abs > 0]),
|
||||||
|
len(results[results.profit_abs < 0])
|
||||||
|
])
|
||||||
|
# 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
|
||||||
|
@ -10,7 +10,6 @@ from pathlib import Path
|
|||||||
from typing import Any, Dict, List, NamedTuple, Optional
|
from typing import Any, Dict, List, NamedTuple, Optional
|
||||||
|
|
||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
from tabulate import tabulate
|
|
||||||
|
|
||||||
from freqtrade.configuration import (TimeRange, remove_credentials,
|
from freqtrade.configuration import (TimeRange, remove_credentials,
|
||||||
validate_config_consistency)
|
validate_config_consistency)
|
||||||
@ -20,7 +19,8 @@ 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.backtest_reports import (
|
||||||
generate_text_table, generate_text_table_sell_reason)
|
generate_text_table, generate_text_table_sell_reason,
|
||||||
|
generate_text_table_strategy)
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
|
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
|
||||||
from freqtrade.state import RunMode
|
from freqtrade.state import RunMode
|
||||||
@ -131,37 +131,6 @@ class Backtesting:
|
|||||||
|
|
||||||
return data, timerange
|
return data, timerange
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _generate_text_table_strategy(self, all_results: dict) -> str:
|
|
||||||
"""
|
|
||||||
Generate summary table per strategy
|
|
||||||
"""
|
|
||||||
stake_currency = str(self.config.get('stake_currency'))
|
|
||||||
max_open_trades = self.config.get('max_open_trades')
|
|
||||||
|
|
||||||
floatfmt = ('s', 'd', '.2f', '.2f', '.8f', '.2f', 'd', '.1f', '.1f')
|
|
||||||
tabular_data = []
|
|
||||||
headers = ['Strategy', 'buy count', 'avg profit %', 'cum profit %',
|
|
||||||
'tot profit ' + stake_currency, 'tot profit %', 'avg duration',
|
|
||||||
'profit', 'loss']
|
|
||||||
for strategy, results in all_results.items():
|
|
||||||
tabular_data.append([
|
|
||||||
strategy,
|
|
||||||
len(results.index),
|
|
||||||
results.profit_percent.mean() * 100.0,
|
|
||||||
results.profit_percent.sum() * 100.0,
|
|
||||||
results.profit_abs.sum(),
|
|
||||||
results.profit_percent.sum() * 100.0 / max_open_trades,
|
|
||||||
str(timedelta(
|
|
||||||
minutes=round(results.trade_duration.mean()))) if not results.empty else '0:00',
|
|
||||||
len(results[results.profit_abs > 0]),
|
|
||||||
len(results[results.profit_abs < 0])
|
|
||||||
])
|
|
||||||
# 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 _store_backtest_result(self, recordfilename: Path, results: DataFrame,
|
def _store_backtest_result(self, recordfilename: Path, results: DataFrame,
|
||||||
strategyname: Optional[str] = None) -> None:
|
strategyname: Optional[str] = None) -> None:
|
||||||
|
|
||||||
@ -469,5 +438,7 @@ class Backtesting:
|
|||||||
if len(all_results) > 1:
|
if len(all_results) > 1:
|
||||||
# Print Strategy summary table
|
# Print Strategy summary table
|
||||||
print(' Strategy Summary '.center(133, '='))
|
print(' Strategy Summary '.center(133, '='))
|
||||||
print(self._generate_text_table_strategy(all_results))
|
print(generate_text_table_strategy(self.config['stake_currency'],
|
||||||
|
self.config['max_open_trades'],
|
||||||
|
all_results=all_results))
|
||||||
print('\nFor more details, please look at the detail tables above')
|
print('\nFor more details, please look at the detail tables above')
|
||||||
|
@ -20,7 +20,8 @@ from freqtrade.data.history import get_timerange
|
|||||||
from freqtrade.exceptions import DependencyException, OperationalException
|
from freqtrade.exceptions import DependencyException, OperationalException
|
||||||
from freqtrade.optimize import setup_configuration, start_backtesting
|
from freqtrade.optimize import setup_configuration, start_backtesting
|
||||||
from freqtrade.optimize.backtest_reports import (
|
from freqtrade.optimize.backtest_reports import (
|
||||||
generate_text_table, generate_text_table_sell_reason)
|
generate_text_table, generate_text_table_sell_reason,
|
||||||
|
generate_text_table_strategy)
|
||||||
from freqtrade.optimize.backtesting import Backtesting
|
from freqtrade.optimize.backtesting import Backtesting
|
||||||
from freqtrade.state import RunMode
|
from freqtrade.state import RunMode
|
||||||
from freqtrade.strategy.default_strategy import DefaultStrategy
|
from freqtrade.strategy.default_strategy import DefaultStrategy
|
||||||
@ -361,7 +362,6 @@ def test_tickerdata_to_dataframe_bt(default_conf, mocker, testdatadir) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_generate_text_table(default_conf, mocker):
|
def test_generate_text_table(default_conf, mocker):
|
||||||
patch_exchange(mocker)
|
|
||||||
|
|
||||||
results = pd.DataFrame(
|
results = pd.DataFrame(
|
||||||
{
|
{
|
||||||
@ -390,7 +390,6 @@ def test_generate_text_table(default_conf, mocker):
|
|||||||
|
|
||||||
|
|
||||||
def test_generate_text_table_sell_reason(default_conf, mocker):
|
def test_generate_text_table_sell_reason(default_conf, mocker):
|
||||||
patch_exchange(mocker)
|
|
||||||
|
|
||||||
results = pd.DataFrame(
|
results = pd.DataFrame(
|
||||||
{
|
{
|
||||||
@ -414,13 +413,7 @@ def test_generate_text_table_sell_reason(default_conf, mocker):
|
|||||||
data={'ETH/BTC': {}}, results=results) == result_str
|
data={'ETH/BTC': {}}, results=results) == result_str
|
||||||
|
|
||||||
|
|
||||||
def test_generate_text_table_strategyn(default_conf, mocker):
|
def test_generate_text_table_strategy(default_conf, mocker):
|
||||||
"""
|
|
||||||
Test Backtesting.generate_text_table_sell_reason() method
|
|
||||||
"""
|
|
||||||
patch_exchange(mocker)
|
|
||||||
default_conf['max_open_trades'] = 2
|
|
||||||
backtesting = Backtesting(default_conf)
|
|
||||||
results = {}
|
results = {}
|
||||||
results['ETH/BTC'] = pd.DataFrame(
|
results['ETH/BTC'] = pd.DataFrame(
|
||||||
{
|
{
|
||||||
@ -455,7 +448,7 @@ def test_generate_text_table_strategyn(default_conf, mocker):
|
|||||||
'| LTC/BTC | 3 | 30.00 | 90.00 '
|
'| LTC/BTC | 3 | 30.00 | 90.00 '
|
||||||
'| 1.30000000 | 45.00 | 0:20:00 | 3 | 0 |'
|
'| 1.30000000 | 45.00 | 0:20:00 | 3 | 0 |'
|
||||||
)
|
)
|
||||||
assert backtesting._generate_text_table_strategy(all_results=results) == result_str
|
assert generate_text_table_strategy('BTC', 2, all_results=results) == result_str
|
||||||
|
|
||||||
|
|
||||||
def test_backtesting_start(default_conf, mocker, testdatadir, caplog) -> None:
|
def test_backtesting_start(default_conf, mocker, testdatadir, caplog) -> None:
|
||||||
|
Loading…
Reference in New Issue
Block a user