Add typed max_drawdown function

This commit is contained in:
Matthias
2024-05-14 19:28:33 +02:00
parent 3b0036368d
commit c8eb22dcbd

View File

@@ -1,5 +1,6 @@
import logging
import math
from dataclasses import dataclass
from datetime import datetime
from typing import Dict, Tuple
@@ -160,14 +161,33 @@ def calculate_underwater(
return max_drawdown_df
def calculate_max_drawdown(
@dataclass()
class DrawDownResult:
__slots__ = [
"drawdown_abs",
"high_date",
"low_date",
"high_value",
"low_value",
"relative_account_drawdown",
]
drawdown_abs: float
high_date: datetime
low_date: datetime
high_value: float
low_value: float
relative_account_drawdown: float
def calc_max_drawdown(
trades: pd.DataFrame,
*,
date_col: str = "close_date",
value_col: str = "profit_abs",
starting_balance: float = 0,
relative: bool = False,
) -> Tuple[float, pd.Timestamp, pd.Timestamp, float, float, float]:
) -> DrawDownResult:
"""
Calculate max drawdown and the corresponding close dates
:param trades: DataFrame containing trades (requires columns close_date and profit_ratio)
@@ -201,13 +221,51 @@ def calculate_max_drawdown(
low_val = max_drawdown_df.loc[idxmin, "cumulative"]
max_drawdown_rel = max_drawdown_df.loc[idxmin, "drawdown_relative"]
return DrawDownResult(
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,
)
def calculate_max_drawdown(
trades: pd.DataFrame,
*,
date_col: str = "close_date",
value_col: str = "profit_abs",
starting_balance: float = 0,
relative: bool = False,
) -> Tuple[float, pd.Timestamp, pd.Timestamp, float, float, float]:
"""
Calculate max drawdown and the corresponding close dates
Deprecated, favor calc_max_drawdown instead!
:param trades: DataFrame containing trades (requires columns close_date and profit_ratio)
: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.
:return: Tuple (float, highdate, lowdate, highvalue, lowvalue, relative_drawdown)
with absolute max drawdown, high and low time and high and low value,
and the relative account drawdown
:raise: ValueError if trade-dataframe was found empty.
"""
# TODO: add deprecation warning
res = calc_max_drawdown(
trades,
date_col=date_col,
value_col=value_col,
starting_balance=starting_balance,
relative=relative,
)
return (
abs(max_drawdown_df.loc[idxmin, "drawdown"]),
high_date,
low_date,
high_val,
low_val,
max_drawdown_rel,
res.drawdown_abs,
res.high_date,
res.low_date,
res.high_value,
res.low_value,
res.relative_account_drawdown,
)