Skip to content

Commit b753231

Browse files
authored
Merge pull request freqtrade#12512 from mrpabloyeah/fix-high_value-calculation-in-calculate_max_drawdown
Fix high_value calculation in calculate_max_drawdown()
2 parents af728f8 + 38ff755 commit b753231

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

freqtrade/data/metrics.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,20 @@ def _calc_drawdown_series(
143143
max_drawdown_df["drawdown_relative"] = (
144144
max_drawdown_df["high_value"] - max_drawdown_df["cumulative"]
145145
) / max_drawdown_df["high_value"]
146+
147+
# Add zero row at start to account for edge-cases with no winning / losing trades - so high/low
148+
# will be 0.0 in such cases.
149+
zero_row = pd.DataFrame(
150+
{
151+
"cumulative": [0.0],
152+
"high_value": [0.0],
153+
"drawdown": [0.0],
154+
"drawdown_relative": [0.0],
155+
"date": [profit_results.loc[0, date_col]],
156+
}
157+
)
158+
159+
max_drawdown_df = pd.concat([zero_row, max_drawdown_df], ignore_index=True)
146160
return max_drawdown_df
147161

148162

@@ -215,6 +229,7 @@ def calculate_max_drawdown(
215229
max_drawdown_df = _calc_drawdown_series(
216230
profit_results, date_col=date_col, value_col=value_col, starting_balance=starting_balance
217231
)
232+
# max_drawdown_df has an extra zero row at the start
218233

219234
# Calculate maximum drawdown
220235
idxmin = (
@@ -223,15 +238,15 @@ def calculate_max_drawdown(
223238
else max_drawdown_df["drawdown"].idxmin()
224239
)
225240
high_idx = max_drawdown_df.iloc[: idxmin + 1]["high_value"].idxmax()
226-
high_date = profit_results.loc[high_idx, date_col]
227-
low_date = profit_results.loc[idxmin, date_col]
228-
high_val = max_drawdown_df.loc[high_idx, "cumulative"]
229-
low_val = max_drawdown_df.loc[idxmin, "cumulative"]
230-
max_drawdown_rel = max_drawdown_df.loc[idxmin, "drawdown_relative"]
241+
high_date = profit_results.at[max(high_idx - 1, 0), date_col]
242+
low_date = profit_results.at[max(idxmin - 1, 0), date_col]
243+
high_val = max_drawdown_df.at[high_idx, "cumulative"]
244+
low_val = max_drawdown_df.at[idxmin, "cumulative"]
245+
max_drawdown_rel = max_drawdown_df.at[idxmin, "drawdown_relative"]
231246

232247
# Calculate current drawdown
233248
current_high_idx = max_drawdown_df["high_value"].iloc[:-1].idxmax()
234-
current_high_date = profit_results.loc[current_high_idx, date_col]
249+
current_high_date = profit_results.at[max(current_high_idx - 1, 0), date_col]
235250
current_high_value = max_drawdown_df.iloc[-1]["high_value"]
236251
current_cumulative = max_drawdown_df.iloc[-1]["cumulative"]
237252
current_drawdown_abs = current_high_value - current_cumulative

tests/data/test_btanalysis.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,12 +575,18 @@ def test_calculate_max_drawdown2():
575575
# No losing trade ...
576576
drawdown = calculate_max_drawdown(df, date_col="open_date", value_col="profit")
577577
assert drawdown.drawdown_abs == 0.0
578+
assert drawdown.low_value == 0.0
579+
assert drawdown.current_high_value >= 0.0
580+
assert drawdown.current_drawdown_abs == 0.0
578581

579582
df1 = DataFrame(zip(values[:5], dates[:5], strict=False), columns=["profit", "open_date"])
580583
df1.loc[:, "profit"] = df1["profit"] * -1
581584
# No winning trade ...
582585
drawdown = calculate_max_drawdown(df1, date_col="open_date", value_col="profit")
583586
assert drawdown.drawdown_abs == 0.055545
587+
assert drawdown.high_value == 0.0
588+
assert drawdown.current_high_value == 0.0
589+
assert drawdown.current_drawdown_abs == 0.055545
584590

585591

586592
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)