mirror of
https://github.com/freqtrade/freqtrade.git
synced 2025-11-29 00:23:07 +00:00
Merge pull request #11899 from mrpabloyeah/add-current-drawdown-in-telegram-profit-command
Add current drawdown in telegram profit command
This commit is contained in:
@@ -174,12 +174,18 @@ def calculate_underwater(
|
||||
|
||||
@dataclass()
|
||||
class DrawDownResult:
|
||||
# Max drawdown fields
|
||||
drawdown_abs: float = 0.0
|
||||
high_date: pd.Timestamp = None
|
||||
low_date: pd.Timestamp = None
|
||||
high_value: float = 0.0
|
||||
low_value: float = 0.0
|
||||
relative_account_drawdown: float = 0.0
|
||||
# Current drawdown fields
|
||||
current_high_date: pd.Timestamp = None
|
||||
current_high_value: float = 0.0
|
||||
current_drawdown_abs: float = 0.0
|
||||
current_relative_account_drawdown: float = 0.0
|
||||
|
||||
|
||||
def calculate_max_drawdown(
|
||||
@@ -191,29 +197,31 @@ def calculate_max_drawdown(
|
||||
relative: bool = False,
|
||||
) -> DrawDownResult:
|
||||
"""
|
||||
Calculate max drawdown and the corresponding close dates
|
||||
:param trades: DataFrame containing trades (requires columns close_date and profit_ratio)
|
||||
Calculate max drawdown and current drawdown with corresponding dates
|
||||
:param trades: DataFrame containing trades (requires columns close_date and profit_abs)
|
||||
:param date_col: Column in DataFrame to use for dates (defaults to 'close_date')
|
||||
:param value_col: Column in DataFrame to use for values (defaults to 'profit_abs')
|
||||
:param starting_balance: Portfolio starting balance - properly calculate relative drawdown.
|
||||
:param relative: If True, use relative drawdown for max calculation instead of absolute
|
||||
:return: DrawDownResult object
|
||||
with absolute max drawdown, high and low time and high and low value,
|
||||
and the relative account drawdown
|
||||
relative account drawdown, and current drawdown information.
|
||||
:raise: ValueError if trade-dataframe was found empty.
|
||||
"""
|
||||
if len(trades) == 0:
|
||||
raise ValueError("Trade dataframe empty.")
|
||||
|
||||
profit_results = trades.sort_values(date_col).reset_index(drop=True)
|
||||
max_drawdown_df = _calc_drawdown_series(
|
||||
profit_results, date_col=date_col, value_col=value_col, starting_balance=starting_balance
|
||||
)
|
||||
|
||||
# Calculate maximum drawdown
|
||||
idxmin = (
|
||||
max_drawdown_df["drawdown_relative"].idxmax()
|
||||
if relative
|
||||
else max_drawdown_df["drawdown"].idxmin()
|
||||
)
|
||||
|
||||
high_idx = max_drawdown_df.iloc[: idxmin + 1]["high_value"].idxmax()
|
||||
high_date = profit_results.loc[high_idx, date_col]
|
||||
low_date = profit_results.loc[idxmin, date_col]
|
||||
@@ -221,13 +229,27 @@ def calculate_max_drawdown(
|
||||
low_val = max_drawdown_df.loc[idxmin, "cumulative"]
|
||||
max_drawdown_rel = max_drawdown_df.loc[idxmin, "drawdown_relative"]
|
||||
|
||||
# Calculate current drawdown
|
||||
current_high_idx = max_drawdown_df["high_value"].iloc[:-1].idxmax()
|
||||
current_high_date = profit_results.loc[current_high_idx, date_col]
|
||||
current_high_value = max_drawdown_df.iloc[-1]["high_value"]
|
||||
current_cumulative = max_drawdown_df.iloc[-1]["cumulative"]
|
||||
current_drawdown_abs = current_high_value - current_cumulative
|
||||
current_drawdown_relative = max_drawdown_df.iloc[-1]["drawdown_relative"]
|
||||
|
||||
return DrawDownResult(
|
||||
# Max drawdown
|
||||
drawdown_abs=abs(max_drawdown_df.loc[idxmin, "drawdown"]),
|
||||
high_date=high_date,
|
||||
low_date=low_date,
|
||||
high_value=high_val,
|
||||
low_value=low_val,
|
||||
relative_account_drawdown=max_drawdown_rel,
|
||||
# Current drawdown
|
||||
current_high_date=current_high_date,
|
||||
current_high_value=current_high_value,
|
||||
current_drawdown_abs=current_drawdown_abs,
|
||||
current_relative_account_drawdown=current_drawdown_relative,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -163,6 +163,11 @@ class Profit(BaseModel):
|
||||
max_drawdown_start_timestamp: int
|
||||
max_drawdown_end: str
|
||||
max_drawdown_end_timestamp: int
|
||||
current_drawdown: float
|
||||
current_drawdown_abs: float
|
||||
current_drawdown_high: float
|
||||
current_drawdown_start: str
|
||||
current_drawdown_start_timestamp: int
|
||||
trading_volume: float | None = None
|
||||
bot_start_timestamp: int
|
||||
bot_start_date: str
|
||||
|
||||
@@ -681,6 +681,11 @@ class RPC:
|
||||
"max_drawdown_end_timestamp": dt_ts_def(drawdown.low_date),
|
||||
"drawdown_high": drawdown.high_value,
|
||||
"drawdown_low": drawdown.low_value,
|
||||
"current_drawdown": drawdown.current_relative_account_drawdown,
|
||||
"current_drawdown_abs": drawdown.current_drawdown_abs,
|
||||
"current_drawdown_high": drawdown.current_high_value,
|
||||
"current_drawdown_start": format_date(drawdown.current_high_date),
|
||||
"current_drawdown_start_timestamp": dt_ts_def(drawdown.current_high_date),
|
||||
"trading_volume": trading_volume,
|
||||
"bot_start_timestamp": dt_ts_def(bot_start, 0),
|
||||
"bot_start_date": format_date(bot_start),
|
||||
|
||||
@@ -1085,6 +1085,10 @@ class Telegram(RPCHandler):
|
||||
f"({fmt_coin(stats['drawdown_high'], stake_cur)})`\n"
|
||||
f" to `{stats['max_drawdown_end']} "
|
||||
f"({fmt_coin(stats['drawdown_low'], stake_cur)})`\n"
|
||||
f"*Current Drawdown:* `{stats['current_drawdown']:.2%} "
|
||||
f"({fmt_coin(stats['current_drawdown_abs'], stake_cur)})`\n"
|
||||
f" from `{stats['current_drawdown_start']} "
|
||||
f"({fmt_coin(stats['current_drawdown_high'], stake_cur)})`\n"
|
||||
)
|
||||
await self._send_msg(
|
||||
markdown_msg,
|
||||
|
||||
@@ -1332,6 +1332,11 @@ def test_api_profit(botclient, mocker, ticker, fee, markets, is_short, expected)
|
||||
"max_drawdown_start_timestamp": ANY,
|
||||
"max_drawdown_end": ANY,
|
||||
"max_drawdown_end_timestamp": ANY,
|
||||
"current_drawdown": ANY,
|
||||
"current_drawdown_abs": ANY,
|
||||
"current_drawdown_high": ANY,
|
||||
"current_drawdown_start": ANY,
|
||||
"current_drawdown_start_timestamp": ANY,
|
||||
"trading_volume": expected["trading_volume"],
|
||||
"bot_start_timestamp": 0,
|
||||
"bot_start_date": "",
|
||||
|
||||
Reference in New Issue
Block a user