Use calc_drawdown method throughout the bot

This commit is contained in:
Matthias
2024-05-14 19:37:41 +02:00
parent 0aa3ec2845
commit 94786454b7
6 changed files with 45 additions and 54 deletions

View File

@@ -408,9 +408,10 @@ def calculate_calmar(
# calculate max drawdown # calculate max drawdown
try: try:
_, _, _, _, _, max_drawdown = calculate_max_drawdown( drawdown = calc_max_drawdown(
trades, value_col="profit_abs", starting_balance=starting_balance trades, value_col="profit_abs", starting_balance=starting_balance
) )
max_drawdown = drawdown.relative_account_drawdown
except ValueError: except ValueError:
max_drawdown = 0 max_drawdown = 0

View File

@@ -9,7 +9,7 @@ from datetime import datetime
from pandas import DataFrame from pandas import DataFrame
from freqtrade.data.metrics import calculate_max_drawdown from freqtrade.data.metrics import calc_max_drawdown
from freqtrade.optimize.hyperopt import IHyperOptLoss from freqtrade.optimize.hyperopt import IHyperOptLoss
@@ -38,8 +38,8 @@ class MaxDrawDownHyperOptLoss(IHyperOptLoss):
""" """
total_profit = results["profit_abs"].sum() total_profit = results["profit_abs"].sum()
try: try:
max_drawdown = calculate_max_drawdown(results, value_col="profit_abs") max_drawdown = calc_max_drawdown(results, value_col="profit_abs")
except ValueError: except ValueError:
# No losing trade, therefore no drawdown. # No losing trade, therefore no drawdown.
return -total_profit return -total_profit
return -total_profit / max_drawdown[0] return -total_profit / max_drawdown.drawdown_abs

View File

@@ -8,12 +8,12 @@ from pandas import DataFrame, Series, concat, to_datetime
from freqtrade.constants import BACKTEST_BREAKDOWNS, DATETIME_PRINT_FORMAT from freqtrade.constants import BACKTEST_BREAKDOWNS, DATETIME_PRINT_FORMAT
from freqtrade.data.metrics import ( from freqtrade.data.metrics import (
calc_max_drawdown,
calculate_cagr, calculate_cagr,
calculate_calmar, calculate_calmar,
calculate_csum, calculate_csum,
calculate_expectancy, calculate_expectancy,
calculate_market_change, calculate_market_change,
calculate_max_drawdown,
calculate_sharpe, calculate_sharpe,
calculate_sortino, calculate_sortino,
) )
@@ -497,29 +497,27 @@ def generate_strategy_stats(
} }
try: try:
max_drawdown_legacy, _, _, _, _, _ = calculate_max_drawdown( max_drawdown_legacy = calc_max_drawdown(results, value_col="profit_ratio")
results, value_col="profit_ratio" drawdown = calc_max_drawdown(
) results, value_col="profit_abs", starting_balance=start_balance
(drawdown_abs, drawdown_start, drawdown_end, high_val, low_val, max_drawdown) = (
calculate_max_drawdown(results, value_col="profit_abs", starting_balance=start_balance)
) )
# max_relative_drawdown = Underwater # max_relative_drawdown = Underwater
(_, _, _, _, _, max_relative_drawdown) = calculate_max_drawdown( underwater = calc_max_drawdown(
results, value_col="profit_abs", starting_balance=start_balance, relative=True results, value_col="profit_abs", starting_balance=start_balance, relative=True
) )
strat_stats.update( strat_stats.update(
{ {
"max_drawdown": max_drawdown_legacy, # Deprecated - do not use "max_drawdown": max_drawdown_legacy.drawdown_abs, # Deprecated - do not use
"max_drawdown_account": max_drawdown, "max_drawdown_account": drawdown.relative_account_drawdown,
"max_relative_drawdown": max_relative_drawdown, "max_relative_drawdown": underwater.relative_account_drawdown,
"max_drawdown_abs": drawdown_abs, "max_drawdown_abs": drawdown.drawdown_abs,
"drawdown_start": drawdown_start.strftime(DATETIME_PRINT_FORMAT), "drawdown_start": drawdown.high_date.strftime(DATETIME_PRINT_FORMAT),
"drawdown_start_ts": drawdown_start.timestamp() * 1000, "drawdown_start_ts": drawdown.high_date.timestamp() * 1000,
"drawdown_end": drawdown_end.strftime(DATETIME_PRINT_FORMAT), "drawdown_end": drawdown.low_date.strftime(DATETIME_PRINT_FORMAT),
"drawdown_end_ts": drawdown_end.timestamp() * 1000, "drawdown_end_ts": drawdown.low_date.timestamp() * 1000,
"max_drawdown_low": low_val, "max_drawdown_low": drawdown.low_value,
"max_drawdown_high": high_val, "max_drawdown_high": drawdown.high_value,
} }
) )

View File

@@ -16,7 +16,7 @@ from freqtrade.data.converter import trim_dataframe
from freqtrade.data.dataprovider import DataProvider from freqtrade.data.dataprovider import DataProvider
from freqtrade.data.history import get_timerange, load_data from freqtrade.data.history import get_timerange, load_data
from freqtrade.data.metrics import ( from freqtrade.data.metrics import (
calculate_max_drawdown, calc_max_drawdown,
calculate_underwater, calculate_underwater,
combine_dataframes_with_mean, combine_dataframes_with_mean,
create_cum_profit, create_cum_profit,
@@ -179,19 +179,17 @@ def add_max_drawdown(
Add scatter points indicating max drawdown Add scatter points indicating max drawdown
""" """
try: try:
_, highdate, lowdate, _, _, max_drawdown = calculate_max_drawdown( drawdown = calc_max_drawdown(trades, starting_balance=starting_balance)
trades, starting_balance=starting_balance
)
drawdown = go.Scatter( drawdown = go.Scatter(
x=[highdate, lowdate], x=[drawdown.high_date, drawdown.low_date],
y=[ y=[
df_comb.loc[timeframe_to_prev_date(timeframe, highdate), "cum_profit"], df_comb.loc[timeframe_to_prev_date(timeframe, drawdown.high_date), "cum_profit"],
df_comb.loc[timeframe_to_prev_date(timeframe, lowdate), "cum_profit"], df_comb.loc[timeframe_to_prev_date(timeframe, drawdown.low_date), "cum_profit"],
], ],
mode="markers", mode="markers",
name=f"Max drawdown {max_drawdown:.2%}", name=f"Max drawdown {drawdown.relative_account_drawdown:.2%}",
text=f"Max drawdown {max_drawdown:.2%}", text=f"Max drawdown {drawdown.relative_account_drawdown:.2%}",
marker=dict(symbol="square-open", size=9, line=dict(width=2), color="green"), marker=dict(symbol="square-open", size=9, line=dict(width=2), color="green"),
) )
fig.add_trace(drawdown, row, 1) fig.add_trace(drawdown, row, 1)

View File

@@ -5,7 +5,7 @@ from typing import Any, Dict, Optional
import pandas as pd import pandas as pd
from freqtrade.constants import Config, LongShort from freqtrade.constants import Config, LongShort
from freqtrade.data.metrics import calculate_max_drawdown from freqtrade.data.metrics import calc_max_drawdown
from freqtrade.persistence import Trade from freqtrade.persistence import Trade
from freqtrade.plugins.protections import IProtection, ProtectionReturn from freqtrade.plugins.protections import IProtection, ProtectionReturn
@@ -59,7 +59,8 @@ class MaxDrawdown(IProtection):
# Drawdown is always positive # Drawdown is always positive
try: try:
# TODO: This should use absolute profit calculation, considering account balance. # TODO: This should use absolute profit calculation, considering account balance.
drawdown, _, _, _, _, _ = calculate_max_drawdown(trades_df, value_col="close_profit") drawdown_obj = calc_max_drawdown(trades_df, value_col="close_profit")
drawdown = drawdown_obj.drawdown_abs
except ValueError: except ValueError:
return None return None

View File

@@ -19,7 +19,11 @@ from freqtrade import __version__
from freqtrade.configuration.timerange import TimeRange from freqtrade.configuration.timerange import TimeRange
from freqtrade.constants import CANCEL_REASON, DEFAULT_DATAFRAME_COLUMNS, Config from freqtrade.constants import CANCEL_REASON, DEFAULT_DATAFRAME_COLUMNS, Config
from freqtrade.data.history import load_data from freqtrade.data.history import load_data
from freqtrade.data.metrics import calculate_expectancy, calculate_max_drawdown from freqtrade.data.metrics import (
DrawDownResult,
calc_max_drawdown,
calculate_expectancy,
)
from freqtrade.enums import ( from freqtrade.enums import (
CandleType, CandleType,
ExitCheckTuple, ExitCheckTuple,
@@ -592,21 +596,10 @@ class RPC:
expectancy, expectancy_ratio = calculate_expectancy(trades_df) expectancy, expectancy_ratio = calculate_expectancy(trades_df)
max_drawdown_abs = 0.0 drawdown = DrawDownResult(0.0, 0.0, None, None, 0.0)
max_drawdown = 0.0
drawdown_start: Optional[datetime] = None
drawdown_end: Optional[datetime] = None
dd_high_val = dd_low_val = 0.0
if len(trades_df) > 0: if len(trades_df) > 0:
try: try:
( drawdown = calc_max_drawdown(
max_drawdown_abs,
drawdown_start,
drawdown_end,
dd_high_val,
dd_low_val,
max_drawdown,
) = calculate_max_drawdown(
trades_df, trades_df,
value_col="profit_abs", value_col="profit_abs",
date_col="close_date_dt", date_col="close_date_dt",
@@ -663,14 +656,14 @@ class RPC:
"winrate": winrate, "winrate": winrate,
"expectancy": expectancy, "expectancy": expectancy,
"expectancy_ratio": expectancy_ratio, "expectancy_ratio": expectancy_ratio,
"max_drawdown": max_drawdown, "max_drawdown": drawdown.relative_account_drawdown,
"max_drawdown_abs": max_drawdown_abs, "max_drawdown_abs": drawdown.drawdown_abs,
"max_drawdown_start": format_date(drawdown_start), "max_drawdown_start": format_date(drawdown.high_date),
"max_drawdown_start_timestamp": dt_ts_def(drawdown_start), "max_drawdown_start_timestamp": dt_ts_def(drawdown.high_date),
"max_drawdown_end": format_date(drawdown_end), "max_drawdown_end": format_date(drawdown.low_date),
"max_drawdown_end_timestamp": dt_ts_def(drawdown_end), "max_drawdown_end_timestamp": dt_ts_def(drawdown.low_date),
"drawdown_high": dd_high_val, "drawdown_high": drawdown.high_value,
"drawdown_low": dd_low_val, "drawdown_low": drawdown.low_value,
"trading_volume": trading_volume, "trading_volume": trading_volume,
"bot_start_timestamp": dt_ts_def(bot_start, 0), "bot_start_timestamp": dt_ts_def(bot_start, 0),
"bot_start_date": format_date(bot_start), "bot_start_date": format_date(bot_start),