store periodic breakdown in backtest results
This will enable the webserver to use this data.
This commit is contained in:
@@ -379,7 +379,8 @@ class Hyperopt:
|
|||||||
|
|
||||||
strat_stats = generate_strategy_stats(
|
strat_stats = generate_strategy_stats(
|
||||||
self.pairlist, self.backtesting.strategy.get_strategy_name(),
|
self.pairlist, self.backtesting.strategy.get_strategy_name(),
|
||||||
backtesting_results, min_date, max_date, market_change=self.market_change
|
backtesting_results, min_date, max_date, market_change=self.market_change,
|
||||||
|
is_hyperopt=True,
|
||||||
)
|
)
|
||||||
results_explanation = HyperoptTools.format_results_explanation_string(
|
results_explanation = HyperoptTools.format_results_explanation_string(
|
||||||
strat_stats, self.config['stake_currency'])
|
strat_stats, self.config['stake_currency'])
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ from typing import Any, Dict, List, Union
|
|||||||
from pandas import DataFrame, to_datetime
|
from pandas import DataFrame, to_datetime
|
||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
|
|
||||||
from freqtrade.constants import (DATETIME_PRINT_FORMAT, LAST_BT_RESULT_FN, UNLIMITED_STAKE_AMOUNT,
|
from freqtrade.constants import (BACKTEST_BREAKDOWNS, DATETIME_PRINT_FORMAT, LAST_BT_RESULT_FN,
|
||||||
Config, IntOrInf)
|
UNLIMITED_STAKE_AMOUNT, Config, IntOrInf)
|
||||||
from freqtrade.data.metrics import (calculate_cagr, calculate_calmar, calculate_csum,
|
from freqtrade.data.metrics import (calculate_cagr, calculate_calmar, calculate_csum,
|
||||||
calculate_expectancy, calculate_market_change,
|
calculate_expectancy, calculate_market_change,
|
||||||
calculate_max_drawdown, calculate_sharpe, calculate_sortino)
|
calculate_max_drawdown, calculate_sharpe, calculate_sortino)
|
||||||
@@ -296,6 +296,7 @@ def generate_periodic_breakdown_stats(trade_list: List, period: str) -> List[Dic
|
|||||||
stats.append(
|
stats.append(
|
||||||
{
|
{
|
||||||
'date': name.strftime('%d/%m/%Y'),
|
'date': name.strftime('%d/%m/%Y'),
|
||||||
|
'date_ts': int(name.to_pydatetime().timestamp() * 1000),
|
||||||
'profit_abs': profit_abs,
|
'profit_abs': profit_abs,
|
||||||
'wins': wins,
|
'wins': wins,
|
||||||
'draws': draws,
|
'draws': draws,
|
||||||
@@ -305,6 +306,13 @@ def generate_periodic_breakdown_stats(trade_list: List, period: str) -> List[Dic
|
|||||||
return stats
|
return stats
|
||||||
|
|
||||||
|
|
||||||
|
def generate_all_periodic_breakdown_stats(trade_list: List) -> Dict[str, List]:
|
||||||
|
result = {}
|
||||||
|
for period in BACKTEST_BREAKDOWNS:
|
||||||
|
result[period] = generate_periodic_breakdown_stats(trade_list, period)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def generate_trading_stats(results: DataFrame) -> Dict[str, Any]:
|
def generate_trading_stats(results: DataFrame) -> Dict[str, Any]:
|
||||||
""" Generate overall trade statistics """
|
""" Generate overall trade statistics """
|
||||||
if len(results) == 0:
|
if len(results) == 0:
|
||||||
@@ -381,7 +389,8 @@ def generate_strategy_stats(pairlist: List[str],
|
|||||||
strategy: str,
|
strategy: str,
|
||||||
content: Dict[str, Any],
|
content: Dict[str, Any],
|
||||||
min_date: datetime, max_date: datetime,
|
min_date: datetime, max_date: datetime,
|
||||||
market_change: float
|
market_change: float,
|
||||||
|
is_hyperopt: bool = False,
|
||||||
) -> Dict[str, Any]:
|
) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:param pairlist: List of pairs to backtest
|
:param pairlist: List of pairs to backtest
|
||||||
@@ -416,6 +425,11 @@ def generate_strategy_stats(pairlist: List[str],
|
|||||||
|
|
||||||
daily_stats = generate_daily_stats(results)
|
daily_stats = generate_daily_stats(results)
|
||||||
trade_stats = generate_trading_stats(results)
|
trade_stats = generate_trading_stats(results)
|
||||||
|
|
||||||
|
periodic_breakdown = {}
|
||||||
|
if not is_hyperopt:
|
||||||
|
periodic_breakdown = {'periodic_breakdown': generate_all_periodic_breakdown_stats(results)}
|
||||||
|
|
||||||
best_pair = max([pair for pair in pair_results if pair['key'] != 'TOTAL'],
|
best_pair = max([pair for pair in pair_results if pair['key'] != 'TOTAL'],
|
||||||
key=lambda x: x['profit_sum']) if len(pair_results) > 1 else None
|
key=lambda x: x['profit_sum']) if len(pair_results) > 1 else None
|
||||||
worst_pair = min([pair for pair in pair_results if pair['key'] != 'TOTAL'],
|
worst_pair = min([pair for pair in pair_results if pair['key'] != 'TOTAL'],
|
||||||
@@ -434,7 +448,6 @@ def generate_strategy_stats(pairlist: List[str],
|
|||||||
'results_per_enter_tag': enter_tag_results,
|
'results_per_enter_tag': enter_tag_results,
|
||||||
'exit_reason_summary': exit_reason_stats,
|
'exit_reason_summary': exit_reason_stats,
|
||||||
'left_open_trades': left_open_results,
|
'left_open_trades': left_open_results,
|
||||||
# 'days_breakdown_stats': days_breakdown_stats,
|
|
||||||
|
|
||||||
'total_trades': len(results),
|
'total_trades': len(results),
|
||||||
'trade_count_long': len(results.loc[~results['is_short']]),
|
'trade_count_long': len(results.loc[~results['is_short']]),
|
||||||
@@ -499,6 +512,7 @@ def generate_strategy_stats(pairlist: List[str],
|
|||||||
'exit_profit_only': config['exit_profit_only'],
|
'exit_profit_only': config['exit_profit_only'],
|
||||||
'exit_profit_offset': config['exit_profit_offset'],
|
'exit_profit_offset': config['exit_profit_offset'],
|
||||||
'ignore_roi_if_entry_signal': config['ignore_roi_if_entry_signal'],
|
'ignore_roi_if_entry_signal': config['ignore_roi_if_entry_signal'],
|
||||||
|
**periodic_breakdown,
|
||||||
**daily_stats,
|
**daily_stats,
|
||||||
**trade_stats
|
**trade_stats
|
||||||
}
|
}
|
||||||
@@ -891,8 +905,11 @@ def show_backtest_result(strategy: str, results: Dict[str, Any], stake_currency:
|
|||||||
print(table)
|
print(table)
|
||||||
|
|
||||||
for period in backtest_breakdown:
|
for period in backtest_breakdown:
|
||||||
days_breakdown_stats = generate_periodic_breakdown_stats(
|
if period in results.get('periodic_breakdown', {}):
|
||||||
trade_list=results['trades'], period=period)
|
days_breakdown_stats = results['periodic_breakdown'][period]
|
||||||
|
else:
|
||||||
|
days_breakdown_stats = generate_periodic_breakdown_stats(
|
||||||
|
trade_list=results['trades'], period=period)
|
||||||
table = text_table_periodic_breakdown(days_breakdown_stats=days_breakdown_stats,
|
table = text_table_periodic_breakdown(days_breakdown_stats=days_breakdown_stats,
|
||||||
stake_currency=stake_currency, period=period)
|
stake_currency=stake_currency, period=period)
|
||||||
if isinstance(table, str) and len(table) > 0:
|
if isinstance(table, str) and len(table) > 0:
|
||||||
|
|||||||
Reference in New Issue
Block a user