add backtesting results abs profit min/abs profit max, to get a better view if a strategy has a enough money to succeed
This commit is contained in:
parent
10a11bda34
commit
5c263c7ffd
@ -383,3 +383,21 @@ def calculate_max_drawdown(trades: pd.DataFrame, *, date_col: str = 'close_date'
|
|||||||
high_date = profit_results.loc[max_drawdown_df.iloc[:idxmin]['high_value'].idxmax(), date_col]
|
high_date = profit_results.loc[max_drawdown_df.iloc[:idxmin]['high_value'].idxmax(), date_col]
|
||||||
low_date = profit_results.loc[idxmin, date_col]
|
low_date = profit_results.loc[idxmin, date_col]
|
||||||
return abs(min(max_drawdown_df['drawdown'])), high_date, low_date
|
return abs(min(max_drawdown_df['drawdown'])), high_date, low_date
|
||||||
|
|
||||||
|
|
||||||
|
def calculate_csum(trades: pd.DataFrame) -> Tuple[float, float]:
|
||||||
|
"""
|
||||||
|
Calculate min/max cumsum of trades, to show if the wallet/stake amount ratio is sane
|
||||||
|
:param trades: DataFrame containing trades (requires columns close_date and profit_percent)
|
||||||
|
:return: Tuple (float, float) with cumsum of profit_abs
|
||||||
|
:raise: ValueError if trade-dataframe was found empty.
|
||||||
|
"""
|
||||||
|
if len(trades) == 0:
|
||||||
|
raise ValueError("Trade dataframe empty.")
|
||||||
|
|
||||||
|
csum_df = pd.DataFrame()
|
||||||
|
csum_df['sum'] = trades['profit_abs'].cumsum()
|
||||||
|
csum_min = csum_df['sum'].min()
|
||||||
|
csum_max = csum_df['sum'].max()
|
||||||
|
|
||||||
|
return csum_min, csum_max
|
||||||
|
@ -9,7 +9,8 @@ from pandas import DataFrame
|
|||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
|
|
||||||
from freqtrade.constants import DATETIME_PRINT_FORMAT, LAST_BT_RESULT_FN
|
from freqtrade.constants import DATETIME_PRINT_FORMAT, LAST_BT_RESULT_FN
|
||||||
from freqtrade.data.btanalysis import calculate_market_change, calculate_max_drawdown
|
from freqtrade.data.btanalysis import (calculate_csum, calculate_market_change,
|
||||||
|
calculate_max_drawdown)
|
||||||
from freqtrade.misc import decimals_per_coin, file_dump_json, round_coin_value
|
from freqtrade.misc import decimals_per_coin, file_dump_json, round_coin_value
|
||||||
|
|
||||||
|
|
||||||
@ -324,6 +325,13 @@ def generate_backtest_stats(btdata: Dict[str, DataFrame],
|
|||||||
'drawdown_end': drawdown_end,
|
'drawdown_end': drawdown_end,
|
||||||
'drawdown_end_ts': drawdown_end.timestamp() * 1000,
|
'drawdown_end_ts': drawdown_end.timestamp() * 1000,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
csum_min, csum_max = calculate_csum(results)
|
||||||
|
strat_stats.update({
|
||||||
|
'csum_min': csum_min,
|
||||||
|
'csum_max': csum_max
|
||||||
|
})
|
||||||
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
strat_stats.update({
|
strat_stats.update({
|
||||||
'max_drawdown': 0.0,
|
'max_drawdown': 0.0,
|
||||||
@ -331,6 +339,8 @@ def generate_backtest_stats(btdata: Dict[str, DataFrame],
|
|||||||
'drawdown_start_ts': 0,
|
'drawdown_start_ts': 0,
|
||||||
'drawdown_end': datetime(1970, 1, 1, tzinfo=timezone.utc),
|
'drawdown_end': datetime(1970, 1, 1, tzinfo=timezone.utc),
|
||||||
'drawdown_end_ts': 0,
|
'drawdown_end_ts': 0,
|
||||||
|
'csum_min': 0,
|
||||||
|
'csum_max': 0
|
||||||
})
|
})
|
||||||
|
|
||||||
strategy_results = generate_strategy_metrics(all_results=all_results)
|
strategy_results = generate_strategy_metrics(all_results=all_results)
|
||||||
@ -439,6 +449,12 @@ def text_table_add_metrics(strat_results: Dict) -> str:
|
|||||||
('Avg. Duration Winners', f"{strat_results['winner_holding_avg']}"),
|
('Avg. Duration Winners', f"{strat_results['winner_holding_avg']}"),
|
||||||
('Avg. Duration Loser', f"{strat_results['loser_holding_avg']}"),
|
('Avg. Duration Loser', f"{strat_results['loser_holding_avg']}"),
|
||||||
('', ''), # Empty line to improve readability
|
('', ''), # Empty line to improve readability
|
||||||
|
|
||||||
|
('Abs Profit Min', round_coin_value(strat_results['csum_min'],
|
||||||
|
strat_results['stake_currency'])),
|
||||||
|
('Abs Profit Max', round_coin_value(strat_results['csum_max'],
|
||||||
|
strat_results['stake_currency'])),
|
||||||
|
|
||||||
('Max Drawdown', f"{round(strat_results['max_drawdown'] * 100, 2)}%"),
|
('Max Drawdown', f"{round(strat_results['max_drawdown'] * 100, 2)}%"),
|
||||||
('Drawdown Start', strat_results['drawdown_start'].strftime(DATETIME_PRINT_FORMAT)),
|
('Drawdown Start', strat_results['drawdown_start'].strftime(DATETIME_PRINT_FORMAT)),
|
||||||
('Drawdown End', strat_results['drawdown_end'].strftime(DATETIME_PRINT_FORMAT)),
|
('Drawdown End', strat_results['drawdown_end'].strftime(DATETIME_PRINT_FORMAT)),
|
||||||
|
Loading…
Reference in New Issue
Block a user