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
try:
_, _, _, _, _, max_drawdown = calculate_max_drawdown(
drawdown = calc_max_drawdown(
trades, value_col="profit_abs", starting_balance=starting_balance
)
max_drawdown = drawdown.relative_account_drawdown
except ValueError:
max_drawdown = 0

View File

@@ -9,7 +9,7 @@ from datetime import datetime
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
@@ -38,8 +38,8 @@ class MaxDrawDownHyperOptLoss(IHyperOptLoss):
"""
total_profit = results["profit_abs"].sum()
try:
max_drawdown = calculate_max_drawdown(results, value_col="profit_abs")
max_drawdown = calc_max_drawdown(results, value_col="profit_abs")
except ValueError:
# No losing trade, therefore no drawdown.
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.data.metrics import (
calc_max_drawdown,
calculate_cagr,
calculate_calmar,
calculate_csum,
calculate_expectancy,
calculate_market_change,
calculate_max_drawdown,
calculate_sharpe,
calculate_sortino,
)
@@ -497,29 +497,27 @@ def generate_strategy_stats(
}
try:
max_drawdown_legacy, _, _, _, _, _ = calculate_max_drawdown(
results, value_col="profit_ratio"
)
(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_drawdown_legacy = calc_max_drawdown(results, value_col="profit_ratio")
drawdown = calc_max_drawdown(
results, value_col="profit_abs", starting_balance=start_balance
)
# 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
)
strat_stats.update(
{
"max_drawdown": max_drawdown_legacy, # Deprecated - do not use
"max_drawdown_account": max_drawdown,
"max_relative_drawdown": max_relative_drawdown,
"max_drawdown_abs": drawdown_abs,
"drawdown_start": drawdown_start.strftime(DATETIME_PRINT_FORMAT),
"drawdown_start_ts": drawdown_start.timestamp() * 1000,
"drawdown_end": drawdown_end.strftime(DATETIME_PRINT_FORMAT),
"drawdown_end_ts": drawdown_end.timestamp() * 1000,
"max_drawdown_low": low_val,
"max_drawdown_high": high_val,
"max_drawdown": max_drawdown_legacy.drawdown_abs, # Deprecated - do not use
"max_drawdown_account": drawdown.relative_account_drawdown,
"max_relative_drawdown": underwater.relative_account_drawdown,
"max_drawdown_abs": drawdown.drawdown_abs,
"drawdown_start": drawdown.high_date.strftime(DATETIME_PRINT_FORMAT),
"drawdown_start_ts": drawdown.high_date.timestamp() * 1000,
"drawdown_end": drawdown.low_date.strftime(DATETIME_PRINT_FORMAT),
"drawdown_end_ts": drawdown.low_date.timestamp() * 1000,
"max_drawdown_low": drawdown.low_value,
"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.history import get_timerange, load_data
from freqtrade.data.metrics import (
calculate_max_drawdown,
calc_max_drawdown,
calculate_underwater,
combine_dataframes_with_mean,
create_cum_profit,
@@ -179,19 +179,17 @@ def add_max_drawdown(
Add scatter points indicating max drawdown
"""
try:
_, highdate, lowdate, _, _, max_drawdown = calculate_max_drawdown(
trades, starting_balance=starting_balance
)
drawdown = calc_max_drawdown(trades, starting_balance=starting_balance)
drawdown = go.Scatter(
x=[highdate, lowdate],
x=[drawdown.high_date, drawdown.low_date],
y=[
df_comb.loc[timeframe_to_prev_date(timeframe, highdate), "cum_profit"],
df_comb.loc[timeframe_to_prev_date(timeframe, lowdate), "cum_profit"],
df_comb.loc[timeframe_to_prev_date(timeframe, drawdown.high_date), "cum_profit"],
df_comb.loc[timeframe_to_prev_date(timeframe, drawdown.low_date), "cum_profit"],
],
mode="markers",
name=f"Max drawdown {max_drawdown:.2%}",
text=f"Max drawdown {max_drawdown:.2%}",
name=f"Max drawdown {drawdown.relative_account_drawdown:.2%}",
text=f"Max drawdown {drawdown.relative_account_drawdown:.2%}",
marker=dict(symbol="square-open", size=9, line=dict(width=2), color="green"),
)
fig.add_trace(drawdown, row, 1)

View File

@@ -5,7 +5,7 @@ from typing import Any, Dict, Optional
import pandas as pd
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.plugins.protections import IProtection, ProtectionReturn
@@ -59,7 +59,8 @@ class MaxDrawdown(IProtection):
# Drawdown is always positive
try:
# 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:
return None

View File

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