--- /mnt/user-data/uploads/intraday_health.py	2026-08-20 04:04:53.569477000 +0000
+++ /tmp/resistance_sim/intraday_health.py	2026-08-21 00:26:08.364530234 +0000
@@ -23,7 +23,13 @@
                 structure (higher highs / higher lows)
     WATCH     - has weakened but not yet confirmed stale/unhealthy
     STALE     - flat/low-participation; NOT necessarily unhealthy, just
-                quiet (a stock can stay healthy while consolidating)
+                quiet (a stock can stay healthy while consolidating).
+                [2026-08-20] Also reached when price_slope is still
+                positive but momentum is decelerating AND at least one
+                other weak signal corroborates (volume declining,
+                lower-highs/lower-lows, or price already lost VWAP) --
+                a fading bounce that hasn't fully broken down yet, but
+                isn't confirming fresh strength either.
     UNHEALTHY - negative slope + VWAP lost + deteriorating structure
                 (lower highs / lower lows)
     REMOVED   - confirmed UNHEALTHY for enough consecutive evaluations
@@ -201,6 +207,7 @@
     max_possible = sum(w.values())
     health_score = round(_clamp(total / max_possible * 100.0, 0, 100), 2)
 
+    momentum_fading = momentum_slope_class == "negative"
     flags = {
         "price_above_vwap": price_above_vwap,
         "higher_highs_higher_lows": hh_hl,
@@ -210,20 +217,57 @@
         "rvol": round(rvol, 2),
         "atr": round(a, 4),
         "no_new_highs": dist_from_high > cfg["no_new_highs_threshold_pct"],
+        "momentum_fading": momentum_fading,
     }
 
     # ---- raw state classification ----
+    #
+    # [FEATURE 2026-08-20] momentum_slope_pct/momentum_slope_class were
+    # computed above (and stored on every HealthReading) since this
+    # module's introduction, but never actually consulted here -- price
+    # direction and the RATE of that price movement are different
+    # questions, and a symbol can keep a positive price_slope for
+    # several bars while its underlying momentum is already
+    # decelerating. That's exactly the pattern behind QUBT's two real
+    # losing entries on 2026-08-20 (09:33 and 09:45): both confirmed
+    # with price_slope=positive (one HEALTHY, one WATCH) and both
+    # stopped out within minutes.
+    #
+    # Two changes:
+    #   1. HEALTHY now additionally requires momentum not be fading --
+    #      a positive price slope propped up by decelerating momentum
+    #      doesn't earn the top tier.
+    #   2. A new, deliberately corroborated-only branch: fading
+    #      momentum ALONE does not downgrade a reading (single-signal
+    #      noise is exactly what this module's hysteresis and
+    #      "_is_severe" pattern already goes out of its way to avoid --
+    #      see this module's docstring). It only reclassifies to STALE
+    #      when at least one other independent weak signal agrees:
+    #      volume declining, lower-highs/lower-lows structure, or price
+    #      having already lost VWAP. This mirrors the existing UNHEALTHY
+    #      branch's require-multiple-signals pattern rather than
+    #      inventing a new, looser standard.
+    #
+    # STALE (unlike WATCH) is NOT entry-eligible -- see
+    # is_eligible_for_entry() below -- and entry_engine.py's fresh
+    # health-reading gate hard-disqualifies any non-HEALTHY/WATCH raw
+    # state at the moment of entry. So this isn't just a relabeling:
+    # a fading-momentum, corroborated reading now actually blocks a
+    # new entry, the same real protection any other STALE read gets.
     severe = _is_severe(price_slope_pct, price_above_vwap, lower_hl, cfg)
     if severe:
         raw_state = "UNHEALTHY"
     elif (price_slope_class == "positive" and vwap_support
-          and not volume_declining and not lower_hl):
+          and not volume_declining and not lower_hl
+          and not momentum_fading):
         raw_state = "HEALTHY"
     elif (price_slope_class == "negative" and not price_above_vwap and lower_hl):
         raw_state = "UNHEALTHY"
     elif (price_slope_class == "flat" and (volume_declining or range_contracting
                                             or flags["no_new_highs"])):
         raw_state = "STALE"
+    elif momentum_fading and (volume_declining or lower_hl or not price_above_vwap):
+        raw_state = "STALE"
     else:
         raw_state = "WATCH"
 
