mirror of
https://github.com/freqtrade/freqtrade.git
synced 2025-11-29 08:33:07 +00:00
Use calc_drawdown method throughout the bot
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
Reference in New Issue
Block a user