From 82bcc96b9f014642c19357768e889a11cb8e3158 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Fri, 31 Jul 2026 00:09:02 +0200 Subject: [PATCH] fix(quickadapter): fail closed on unmeasurable entry history (#193) * fix(quickadapter): fail closed on unmeasurable entry history Reject reversal entries when configured historical confirmation is non-finite, while preserving a valid current-candle exit result for exposure reduction. * docs(quickadapter): drop internal fallback note from lookback tunable The reversal_confirmation.lookback_period_candles row documents user-facing usage; the non-finite historical confirmation fallback is an internal implementation detail already described in reversal_confirmed's docstring. Keep the tunable description terse and avoid duplicating internals per the repository documentation conventions. --- .../user_data/strategies/QuickAdapterV3.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/quickadapter/user_data/strategies/QuickAdapterV3.py b/quickadapter/user_data/strategies/QuickAdapterV3.py index 1e9f643..f52c38e 100644 --- a/quickadapter/user_data/strategies/QuickAdapterV3.py +++ b/quickadapter/user_data/strategies/QuickAdapterV3.py @@ -1945,11 +1945,12 @@ class QuickAdapterV3(IStrategy): each ``k = 1..lookback_period_candles`` the close at ``-k`` strictly broke the threshold recomputed at ``-(k+1)`` with the natr-multiplier bounds geometrically decayed by ``decay_fraction ** k`` clamped to - ``[0, 1]``. Non-finite intermediate close or threshold aborts the chain - and falls back permissively to the current-candle result, which may - weaken strict multi-candle guarantees. Returns False on empty - dataframe, invalid side/order, non-finite rate, negative lookback, - ``decay_fraction`` outside ``(0, 1]``, or invalid min/max ordering. + ``[0, 1]``. A non-finite intermediate close or threshold aborts the + chain: entries fail closed, while exits retain the valid current-candle + result to allow exposure reduction without guaranteeing a profitable + exit. Returns False on empty dataframe, invalid side/order, non-finite + rate, negative lookback, ``decay_fraction`` outside ``(0, 1]``, or + invalid min/max ordering. """ if df.empty: return False @@ -2013,10 +2014,11 @@ class QuickAdapterV3(IStrategy): if lookback_period_candles == 0: return current_ok + unmeasurable_history_ok = order == QuickAdapterV3._ORDER_EXIT and current_ok for k in range(1, lookback_period_candles + 1): close_k = df.iloc[-k].get("close") if not isinstance(close_k, (int, float)) or not np.isfinite(close_k): - return current_ok + return unmeasurable_history_ok decay_factor = decay_fraction**k decayed_min_natr_multiplier_fraction = max( @@ -2038,7 +2040,7 @@ class QuickAdapterV3(IStrategy): if not isinstance(threshold_k, (int, float)) or not np.isfinite( threshold_k ): - return current_ok + return unmeasurable_history_ok if (side == QuickAdapterV3._TRADE_LONG and not (close_k > threshold_k)) or ( side == QuickAdapterV3._TRADE_SHORT and not (close_k < threshold_k) -- 2.53.0