refactor: Type backtest results

This commit is contained in:
Matthias
2025-04-06 14:38:51 +02:00
parent ca390eea6a
commit 4986f356ee
5 changed files with 44 additions and 9 deletions
+2
View File
@@ -1,5 +1,7 @@
# flake8: noqa: F401 # flake8: noqa: F401
from freqtrade.ft_types.backtest_result_type import ( from freqtrade.ft_types.backtest_result_type import (
BacktestContentType,
BacktestContentTypeIcomplete,
BacktestHistoryEntryType, BacktestHistoryEntryType,
BacktestMetadataType, BacktestMetadataType,
BacktestResultType, BacktestResultType,
@@ -1,8 +1,11 @@
from copy import deepcopy from copy import deepcopy
from typing import Any, cast from typing import Any, cast
from pandas import DataFrame
from typing_extensions import TypedDict from typing_extensions import TypedDict
from freqtrade.constants import Config
class BacktestMetadataType(TypedDict): class BacktestMetadataType(TypedDict):
run_id: str run_id: str
@@ -36,3 +39,22 @@ class BacktestHistoryEntryType(BacktestMetadataType):
backtest_end_ts: int | None backtest_end_ts: int | None
timeframe: str | None timeframe: str | None
timeframe_detail: str | None timeframe_detail: str | None
class BacktestContentTypeIcomplete(TypedDict, total=False):
results: DataFrame
config: Config
locks: Any
rejected_signals: int
timedout_entry_orders: int
timedout_exit_orders: int
canceled_trade_entries: int
canceled_entry_orders: int
replaced_entry_orders: int
final_balance: float
backtest_start_time: int
backtest_end_time: int
run_id: str
class BacktestContentType(BacktestContentTypeIcomplete, total=True): ...
+10 -4
View File
@@ -8,7 +8,6 @@ import logging
from collections import defaultdict from collections import defaultdict
from copy import deepcopy from copy import deepcopy
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Any
from numpy import nan from numpy import nan
from pandas import DataFrame from pandas import DataFrame
@@ -37,7 +36,12 @@ from freqtrade.exchange import (
timeframe_to_seconds, timeframe_to_seconds,
) )
from freqtrade.exchange.exchange import Exchange from freqtrade.exchange.exchange import Exchange
from freqtrade.ft_types import BacktestResultType, get_BacktestResultType_default from freqtrade.ft_types import (
BacktestContentType,
BacktestContentTypeIcomplete,
BacktestResultType,
get_BacktestResultType_default,
)
from freqtrade.leverage.liquidation_price import update_liquidation_prices from freqtrade.leverage.liquidation_price import update_liquidation_prices
from freqtrade.mixins import LoggingMixin from freqtrade.mixins import LoggingMixin
from freqtrade.optimize.backtest_caching import get_strategy_run_id from freqtrade.optimize.backtest_caching import get_strategy_run_id
@@ -119,7 +123,7 @@ class Backtesting:
config["dry_run"] = True config["dry_run"] = True
self.run_ids: dict[str, str] = {} self.run_ids: dict[str, str] = {}
self.strategylist: list[IStrategy] = [] self.strategylist: list[IStrategy] = []
self.all_results: dict[str, dict] = {} self.all_results: dict[str, BacktestContentType] = {}
self.analysis_results: dict[str, dict[str, DataFrame]] = { self.analysis_results: dict[str, dict[str, DataFrame]] = {
"signals": {}, "signals": {},
"rejected": {}, "rejected": {},
@@ -1611,7 +1615,9 @@ class Backtesting:
yield current_time_det, pair, row, is_last_row, trade_dir yield current_time_det, pair, row, is_last_row, trade_dir
self.progress.increment() self.progress.increment()
def backtest(self, processed: dict, start_date: datetime, end_date: datetime) -> dict[str, Any]: def backtest(
self, processed: dict, start_date: datetime, end_date: datetime
) -> BacktestContentTypeIcomplete:
""" """
Implement backtesting functionality Implement backtesting functionality
@@ -19,6 +19,7 @@ from freqtrade.data.history import get_timerange
from freqtrade.data.metrics import calculate_market_change from freqtrade.data.metrics import calculate_market_change
from freqtrade.enums import HyperoptState from freqtrade.enums import HyperoptState
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.ft_types import BacktestContentType
from freqtrade.misc import deep_merge_dicts from freqtrade.misc import deep_merge_dicts
from freqtrade.optimize.backtesting import Backtesting from freqtrade.optimize.backtesting import Backtesting
@@ -324,7 +325,7 @@ class HyperOptimizer:
def _get_results_dict( def _get_results_dict(
self, self,
backtesting_results: dict[str, Any], backtesting_results: BacktestContentType,
min_date: datetime, min_date: datetime,
max_date: datetime, max_date: datetime,
params_dict: dict[str, Any], params_dict: dict[str, Any],
@@ -18,7 +18,11 @@ from freqtrade.data.metrics import (
calculate_sortino, calculate_sortino,
calculate_sqn, calculate_sqn,
) )
from freqtrade.ft_types import BacktestResultType, get_BacktestResultType_default from freqtrade.ft_types import (
BacktestContentType,
BacktestResultType,
get_BacktestResultType_default,
)
from freqtrade.util import decimals_per_coin, fmt_coin, get_dry_run_wallet from freqtrade.util import decimals_per_coin, fmt_coin, get_dry_run_wallet
@@ -26,7 +30,7 @@ logger = logging.getLogger(__name__)
def generate_trade_signal_candles( def generate_trade_signal_candles(
preprocessed_df: dict[str, DataFrame], bt_results: dict[str, Any], date_col: str preprocessed_df: dict[str, DataFrame], bt_results: BacktestContentType, date_col: str
) -> dict[str, DataFrame]: ) -> dict[str, DataFrame]:
signal_candles_only = {} signal_candles_only = {}
for pair in preprocessed_df.keys(): for pair in preprocessed_df.keys():
@@ -407,7 +411,7 @@ def generate_daily_stats(results: DataFrame) -> dict[str, Any]:
def generate_strategy_stats( def generate_strategy_stats(
pairlist: list[str], pairlist: list[str],
strategy: str, strategy: str,
content: dict[str, Any], content: BacktestContentType,
min_date: datetime, min_date: datetime,
max_date: datetime, max_date: datetime,
market_change: float, market_change: float,
@@ -632,7 +636,7 @@ def generate_strategy_stats(
def generate_backtest_stats( def generate_backtest_stats(
btdata: dict[str, DataFrame], btdata: dict[str, DataFrame],
all_results: dict[str, dict[str, DataFrame | dict]], all_results: dict[str, BacktestContentType],
min_date: datetime, min_date: datetime,
max_date: datetime, max_date: datetime,
) -> BacktestResultType: ) -> BacktestResultType: