refactor: move some utils to a separate file
This commit is contained in:
@@ -1,9 +1,7 @@
|
|||||||
# flake8: noqa: F401
|
# flake8: noqa: F401
|
||||||
from .btanalysis import (
|
from .btanalysis import (
|
||||||
BT_DATA_COLUMNS,
|
BT_DATA_COLUMNS,
|
||||||
analyze_trade_parallelism,
|
|
||||||
delete_backtest_result,
|
delete_backtest_result,
|
||||||
evaluate_result_multi,
|
|
||||||
extract_trades_of_period,
|
extract_trades_of_period,
|
||||||
find_existing_backtest_stats,
|
find_existing_backtest_stats,
|
||||||
get_backtest_market_change,
|
get_backtest_market_change,
|
||||||
@@ -27,3 +25,7 @@ from .btanalysis import (
|
|||||||
trade_list_to_dataframe,
|
trade_list_to_dataframe,
|
||||||
update_backtest_metadata,
|
update_backtest_metadata,
|
||||||
)
|
)
|
||||||
|
from .trade_parallelism import (
|
||||||
|
analyze_trade_parallelism,
|
||||||
|
evaluate_result_multi,
|
||||||
|
)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from typing import Any, Literal
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
from freqtrade.constants import LAST_BT_RESULT_FN, IntOrInf
|
from freqtrade.constants import LAST_BT_RESULT_FN
|
||||||
from freqtrade.exceptions import ConfigurationError, OperationalException
|
from freqtrade.exceptions import ConfigurationError, OperationalException
|
||||||
from freqtrade.ft_types import BacktestHistoryEntryType, BacktestResultType
|
from freqtrade.ft_types import BacktestHistoryEntryType, BacktestResultType
|
||||||
from freqtrade.misc import file_dump_json, json_load
|
from freqtrade.misc import file_dump_json, json_load
|
||||||
@@ -491,57 +491,6 @@ def load_exit_signal_candles(backtest_dir: Path) -> dict[str, dict[str, pd.DataF
|
|||||||
return load_backtest_analysis_data(backtest_dir, "exited")
|
return load_backtest_analysis_data(backtest_dir, "exited")
|
||||||
|
|
||||||
|
|
||||||
def analyze_trade_parallelism(trades: pd.DataFrame, timeframe: str) -> pd.DataFrame:
|
|
||||||
"""
|
|
||||||
Find overlapping trades by expanding each trade once per period it was open
|
|
||||||
and then counting overlaps.
|
|
||||||
:param trades: Trades Dataframe - can be loaded from backtest, or created
|
|
||||||
via trade_list_to_dataframe
|
|
||||||
:param timeframe: Timeframe used for backtest
|
|
||||||
:return: dataframe with open-counts per time-period in timeframe
|
|
||||||
"""
|
|
||||||
from freqtrade.exchange import timeframe_to_resample_freq
|
|
||||||
|
|
||||||
timeframe_freq = timeframe_to_resample_freq(timeframe)
|
|
||||||
dates = [
|
|
||||||
pd.Series(
|
|
||||||
pd.date_range(
|
|
||||||
row[1]["open_date"],
|
|
||||||
row[1]["close_date"],
|
|
||||||
freq=timeframe_freq,
|
|
||||||
# Exclude right boundary - the date is the candle open date.
|
|
||||||
inclusive="left",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
for row in trades[["open_date", "close_date"]].iterrows()
|
|
||||||
]
|
|
||||||
deltas = [len(x) for x in dates]
|
|
||||||
dates = pd.Series(pd.concat(dates).values, name="date")
|
|
||||||
df2 = pd.DataFrame(np.repeat(trades.values, deltas, axis=0), columns=trades.columns)
|
|
||||||
|
|
||||||
df2 = pd.concat([dates, df2], axis=1)
|
|
||||||
df2 = df2.set_index("date")
|
|
||||||
df_final = df2.resample(timeframe_freq)[["pair"]].count()
|
|
||||||
df_final = df_final.rename({"pair": "open_trades"}, axis=1)
|
|
||||||
return df_final
|
|
||||||
|
|
||||||
|
|
||||||
def evaluate_result_multi(
|
|
||||||
trades: pd.DataFrame, timeframe: str, max_open_trades: IntOrInf
|
|
||||||
) -> pd.DataFrame:
|
|
||||||
"""
|
|
||||||
Find overlapping trades by expanding each trade once per period it was open
|
|
||||||
and then counting overlaps
|
|
||||||
:param trades: Trades Dataframe - can be loaded from backtest, or created
|
|
||||||
via trade_list_to_dataframe
|
|
||||||
:param timeframe: Frequency used for the backtest
|
|
||||||
:param max_open_trades: parameter max_open_trades used during backtest run
|
|
||||||
:return: dataframe with open-counts per time-period in freq
|
|
||||||
"""
|
|
||||||
df_final = analyze_trade_parallelism(trades, timeframe)
|
|
||||||
return df_final[df_final["open_trades"] > max_open_trades]
|
|
||||||
|
|
||||||
|
|
||||||
def trade_list_to_dataframe(trades: list[Trade] | list[LocalTrade]) -> pd.DataFrame:
|
def trade_list_to_dataframe(trades: list[Trade] | list[LocalTrade]) -> pd.DataFrame:
|
||||||
"""
|
"""
|
||||||
Convert list of Trade objects to pandas Dataframe
|
Convert list of Trade objects to pandas Dataframe
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
from freqtrade.constants import IntOrInf
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def analyze_trade_parallelism(trades: pd.DataFrame, timeframe: str) -> pd.DataFrame:
|
||||||
|
"""
|
||||||
|
Find overlapping trades by expanding each trade once per period it was open
|
||||||
|
and then counting overlaps.
|
||||||
|
:param trades: Trades Dataframe - can be loaded from backtest, or created
|
||||||
|
via trade_list_to_dataframe
|
||||||
|
:param timeframe: Timeframe used for backtest
|
||||||
|
:return: dataframe with open-counts per time-period in timeframe
|
||||||
|
"""
|
||||||
|
from freqtrade.exchange import timeframe_to_resample_freq
|
||||||
|
|
||||||
|
timeframe_freq = timeframe_to_resample_freq(timeframe)
|
||||||
|
dates = [
|
||||||
|
pd.Series(
|
||||||
|
pd.date_range(
|
||||||
|
row[1]["open_date"],
|
||||||
|
row[1]["close_date"],
|
||||||
|
freq=timeframe_freq,
|
||||||
|
# Exclude right boundary - the date is the candle open date.
|
||||||
|
inclusive="left",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
for row in trades[["open_date", "close_date"]].iterrows()
|
||||||
|
]
|
||||||
|
deltas = [len(x) for x in dates]
|
||||||
|
dates = pd.Series(pd.concat(dates).values, name="date")
|
||||||
|
df2 = pd.DataFrame(np.repeat(trades.values, deltas, axis=0), columns=trades.columns)
|
||||||
|
|
||||||
|
df2 = pd.concat([dates, df2], axis=1)
|
||||||
|
df2 = df2.set_index("date")
|
||||||
|
df_final = df2.resample(timeframe_freq)[["pair"]].count()
|
||||||
|
df_final = df_final.rename({"pair": "open_trades"}, axis=1)
|
||||||
|
return df_final
|
||||||
|
|
||||||
|
|
||||||
|
def evaluate_result_multi(
|
||||||
|
trades: pd.DataFrame, timeframe: str, max_open_trades: IntOrInf
|
||||||
|
) -> pd.DataFrame:
|
||||||
|
"""
|
||||||
|
Find overlapping trades by expanding each trade once per period it was open
|
||||||
|
and then counting overlaps
|
||||||
|
:param trades: Trades Dataframe - can be loaded from backtest, or created
|
||||||
|
via trade_list_to_dataframe
|
||||||
|
:param timeframe: Frequency used for the backtest
|
||||||
|
:param max_open_trades: parameter max_open_trades used during backtest run
|
||||||
|
:return: dataframe with open-counts per time-period in freq
|
||||||
|
"""
|
||||||
|
df_final = analyze_trade_parallelism(trades, timeframe)
|
||||||
|
return df_final[df_final["open_trades"] > max_open_trades]
|
||||||
Reference in New Issue
Block a user