Skip to content

Commit b3b21e6

Browse files
committed
fix: market_change deviation between backtesting and hyperopt
closes freqtrade#11672
1 parent b8b4b2d commit b3b21e6

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

freqtrade/data/metrics.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
logger = logging.getLogger(__name__)
1111

1212

13-
def calculate_market_change(data: dict[str, pd.DataFrame], column: str = "close") -> float:
13+
def calculate_market_change(
14+
data: dict[str, pd.DataFrame], column: str = "close", min_date: datetime | None = None
15+
) -> float:
1416
"""
1517
Calculate market change based on "column".
1618
Calculation is done by taking the first non-null and the last non-null element of each column
@@ -19,14 +21,24 @@ def calculate_market_change(data: dict[str, pd.DataFrame], column: str = "close"
1921
2022
:param data: Dict of Dataframes, dict key should be pair.
2123
:param column: Column in the original dataframes to use
24+
:param min_date: Minimum date to consider for calculations. Market change should only be
25+
calculated for data actually backtested, excluding startup periods.
2226
:return:
2327
"""
2428
tmp_means = []
2529
for pair, df in data.items():
26-
start = df[column].dropna().iloc[0]
27-
end = df[column].dropna().iloc[-1]
30+
df1 = df
31+
if min_date is not None:
32+
df1 = df1[df1["date"] >= min_date]
33+
if df1.empty:
34+
logger.warning(f"Pair {pair} has no data after {min_date}.")
35+
continue
36+
start = df1[column].dropna().iloc[0]
37+
end = df1[column].dropna().iloc[-1]
2838
tmp_means.append((end - start) / start)
2939

40+
if not tmp_means:
41+
return 0.0
3042
return float(np.mean(tmp_means))
3143

3244

freqtrade/optimize/optimize_reports/optimize_reports.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ def generate_backtest_stats(
649649
:return: Dictionary containing results per strategy and a strategy summary.
650650
"""
651651
result: BacktestResultType = get_BacktestResultType_default()
652-
market_change = calculate_market_change(btdata, "close")
652+
market_change = calculate_market_change(btdata, "close", min_date=min_date)
653653
metadata = {}
654654
pairlist = list(btdata.keys())
655655
for strategy, content in all_results.items():

0 commit comments

Comments
 (0)