]> Piment Noir Git Repositories - freqai-strategies.git/commitdiff
perf(qav3): code optimizations
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Fri, 8 Aug 2025 22:32:59 +0000 (00:32 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Fri, 8 Aug 2025 22:32:59 +0000 (00:32 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
quickadapter/user_data/strategies/QuickAdapterV3.py
quickadapter/user_data/strategies/Utils.py

index 34899fc4b526f90ce1b1c4f0a2395053008a0220..9bd66c278f2d5a2c31f77211709649375231e1e1 100644 (file)
@@ -433,12 +433,13 @@ class QuickAdapterV3(IStrategy):
         return self.get_label_natr_ratio(pair) * percent
 
     @staticmethod
+    @lru_cache(maxsize=128)
     def td_format(
         delta: datetime.timedelta, pattern: str = "{sign}{d}:{h:02d}:{m:02d}:{s:02d}"
     ) -> str:
         negative_duration = delta.total_seconds() < 0
         delta = abs(delta)
-        duration = {"d": delta.days}
+        duration: dict[str, Any] = {"d": delta.days}
         duration["h"], remainder = divmod(delta.seconds, 3600)
         duration["m"], duration["s"] = divmod(remainder, 60)
         duration["ms"] = delta.microseconds // 1000
@@ -572,6 +573,7 @@ class QuickAdapterV3(IStrategy):
         )
 
     @staticmethod
+    @lru_cache(maxsize=128)
     def is_trade_duration_valid(trade_duration: Optional[int | float]) -> bool:
         return isinstance(trade_duration, (int, float)) and not (
             isna(trade_duration) or trade_duration <= 0
@@ -1077,6 +1079,7 @@ class QuickAdapterV3(IStrategy):
         )
 
     @staticmethod
+    @lru_cache(maxsize=128)
     def is_isoformat(string: str) -> bool:
         if not isinstance(string, str):
             return False
index 826d9bc09b58b92414b04b0c2c54598db8077c3d..f9ede236ff7b4af738abaff3fa6082b7940e069a 100644 (file)
@@ -112,12 +112,15 @@ def smooth_extrema(
     )
 
 
+@lru_cache(maxsize=128)
 def format_number(value: int | float, significant_digits: int = 5) -> str:
     if not isinstance(value, (int, float)):
         return str(value)
 
-    if np.isinf(value):
-        return "+∞" if value > 0 else "-∞"
+    if np.isposinf(value):
+        return "+∞"
+    if np.isneginf(value):
+        return "-∞"
     if np.isnan(value):
         return "NaN"
 
@@ -129,18 +132,11 @@ def format_number(value: int | float, significant_digits: int = 5) -> str:
     if abs_value >= 1.0:
         precision = significant_digits
     else:
-        value_str = f"{abs_value:.18f}"
-        first_digit_pos = -1
-        for i, char in enumerate(value_str):
-            if char > "0" and char <= "9":
-                first_digit_pos = i
-                break
-
-        if first_digit_pos == -1:
-            precision = significant_digits
-        else:
-            leading_zeros = first_digit_pos - 2
-            precision = leading_zeros + significant_digits
+        if abs_value == 0:
+            return "0"
+        order_of_magnitude = math.floor(math.log10(abs_value))
+        leading_zeros = abs(order_of_magnitude) - 1
+        precision = leading_zeros + significant_digits
 
     formatted_value = f"{value:.{precision}f}"
 
@@ -240,6 +236,7 @@ def calculate_zero_lag(series: pd.Series, period: int) -> pd.Series:
     return 2 * series - series.shift(int(lag))
 
 
+@lru_cache(maxsize=8)
 def get_ma_fn(mamode: str) -> Callable[[pd.Series, int], np.ndarray]:
     mamodes: dict[str, Callable[[pd.Series, int], np.ndarray]] = {
         "sma": ta.SMA,
@@ -254,6 +251,7 @@ def get_ma_fn(mamode: str) -> Callable[[pd.Series, int], np.ndarray]:
     return mamodes.get(mamode, mamodes["sma"])
 
 
+@lru_cache(maxsize=8)
 def get_zl_ma_fn(mamode: str) -> Callable[[pd.Series, int], np.ndarray]:
     ma_fn = get_ma_fn(mamode)
     return lambda series, timeperiod: ma_fn(
@@ -935,6 +933,7 @@ def soft_extremum(series: pd.Series, alpha: float) -> float:
     return numerator / denominator
 
 
+@lru_cache(maxsize=128)
 def round_to_nearest_int(value: float, step: int) -> int:
     """
     Round a value to the nearest multiple of a given step.