From: Jérôme Benoit Date: Fri, 2 Jan 2026 17:29:04 +0000 (+0100) Subject: refactor(quickadapter): cleanup timeframe_minutes usage X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=94bf75815f17d0b1bbdc9bca79ce413a3877032f;p=freqai-strategies.git refactor(quickadapter): cleanup timeframe_minutes usage Signed-off-by: Jérôme Benoit --- diff --git a/quickadapter/user_data/strategies/QuickAdapterV3.py b/quickadapter/user_data/strategies/QuickAdapterV3.py index b70d204..52254c3 100644 --- a/quickadapter/user_data/strategies/QuickAdapterV3.py +++ b/quickadapter/user_data/strategies/QuickAdapterV3.py @@ -109,6 +109,7 @@ class QuickAdapterV3(IStrategy): return "3.9.1" timeframe = "5m" + timeframe_minutes = timeframe_to_minutes(timeframe) stoploss = -0.025 use_custom_stoploss = True @@ -147,16 +148,16 @@ class QuickAdapterV3(IStrategy): _PLOT_EXTREMA_MIN_EPS: Final[float] = 0.01 - timeframe_minutes = timeframe_to_minutes(timeframe) - minimal_roi = {str(timeframe_minutes * 864): -1} # FreqAI is crashing if minimal_roi is a property # @property # def minimal_roi(self) -> dict[str, Any]: - # timeframe_minutes = timeframe_to_minutes(self.config.get("timeframe", "5m")) + # timeframe_minutes = self.get_timeframe_minutes() # fit_live_predictions_candles = int( - # self.config.get("freqai", {}).get("fit_live_predictions_candles", DEFAULT_FIT_LIVE_PREDICTIONS_CANDLES) + # self.config.get("freqai", {}).get( + # "fit_live_predictions_candles", DEFAULT_FIT_LIVE_PREDICTIONS_CANDLES + # ) # ) # return {str(timeframe_minutes * fit_live_predictions_candles): -1} @@ -167,15 +168,18 @@ class QuickAdapterV3(IStrategy): process_only_new_candles = True @staticmethod + @lru_cache(maxsize=None) def _trade_directions_set() -> set[TradeDirection]: - return { - QuickAdapterV3._TRADE_DIRECTIONS[0], - QuickAdapterV3._TRADE_DIRECTIONS[1], - } + return set(QuickAdapterV3._TRADE_DIRECTIONS) @staticmethod + @lru_cache(maxsize=None) def _order_types_set() -> set[OrderType]: - return {QuickAdapterV3._ORDER_TYPES[0], QuickAdapterV3._ORDER_TYPES[1]} + return set(QuickAdapterV3._ORDER_TYPES) + + @lru_cache(maxsize=None) + def get_timeframe_minutes(self) -> int: + return timeframe_to_minutes(self.config.get("timeframe")) @property def can_short(self) -> bool: @@ -465,9 +469,7 @@ class QuickAdapterV3(IStrategy): ), } ) - self._candle_duration_secs = int( - timeframe_to_minutes(self.config.get("timeframe")) * 60 - ) + self._candle_duration_secs = int(self.get_timeframe_minutes() * 60) self.last_candle_start_secs: dict[str, Optional[int]] = {} process_throttle_secs = self.config.get("internals", {}).get( "process_throttle_secs", 5 @@ -1167,7 +1169,7 @@ class QuickAdapterV3(IStrategy): natr_multiplier=label_natr_multiplier, ) label_period = datetime.timedelta( - minutes=len(dataframe) * timeframe_to_minutes(self.config.get("timeframe")) + minutes=len(dataframe) * self.get_timeframe_minutes() ) dataframe[EXTREMA_COLUMN] = 0.0 dataframe["minima"] = 0.0 @@ -1317,7 +1319,7 @@ class QuickAdapterV3(IStrategy): return None return int( ((current_date - entry_date).total_seconds() / 60.0) - / timeframe_to_minutes(self.config.get("timeframe")) + / self.get_timeframe_minutes() ) def get_trade_annotation_line_start_date( @@ -1334,9 +1336,8 @@ class QuickAdapterV3(IStrategy): - (trade_duration_candles if trade_duration_candles is not None else 0), ) - timeframe_minutes = timeframe_to_minutes(self.config.get("timeframe")) offset_timedelta = datetime.timedelta( - minutes=offset_candles_remaining * timeframe_minutes + minutes=offset_candles_remaining * self.get_timeframe_minutes() ) return trade.open_date_utc - offset_timedelta @@ -2147,8 +2148,8 @@ class QuickAdapterV3(IStrategy): if ( side == QuickAdapterV3._TRADE_DIRECTIONS[0] - and not (close_k > threshold_k) - ) or ( # "long" + and not (close_k > threshold_k) # "long" + ) or ( side == QuickAdapterV3._TRADE_DIRECTIONS[1] and not (close_k < threshold_k) # "short" ):