Population gate audit: static overnight gap everywhere + full band
The 2026-07-08 audit (owner: "figure out if there is some kind of logic or audit issue") found BOTH entry paths feeding the population gate the WRONG gap. The fast path used the trigger book's dynamic gap (latest price vs prev close), so intraday rallies masqueraded as gappers: TVRD (6.0% true gap), SKIN (2.2%, filled at $0.98), JLHL (4.3%) all traded outside the validated population. The slow path used max(gap, intraday) with "open" taken from the first lookback-window bar, and had no upper band at all — dead-band names SEER (38.6%) and IOTR (40.7%) entered. Fixes: candidates carry gap_open_pct (session open vs prev close); trigger eligibility + submit_breakout_now use it exclusively once the session is open; _population_reject now implements the full validated band (10-35% OR volume-verified >=150% squeeze, $1-20 price band) for both paths; evaluator gap uses the session open; signals carry relative_volume for squeeze verification. Plus momentum-testpg.service so the test-isolation Postgres survives reboots. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
2e5346e035
commit
44ff36a669
8 files changed
+103
-13
No files matched your search
@@ -18,10 +18,11 @@ SCANNER_VERSION = "gapper-v2"
|
||||
class GapperCandidate:
|
||||
symbol: str
|
||||
price: float
|
||||
gap_pct: float
|
||||
gap_pct: float # DYNAMIC: latest close vs prev close (display/rank)
|
||||
cumulative_volume: int
|
||||
relative_volume: float
|
||||
vwap: float | None
|
||||
prev_close: float | None = None # for the STATIC overnight gap (open vs prev close)
|
||||
rank: int = 0
|
||||
|
||||
|
||||
@@ -88,6 +89,7 @@ def scan_gappers(
|
||||
GapperCandidate(
|
||||
symbol=symbol,
|
||||
price=float(close),
|
||||
prev_close=float(prev_close),
|
||||
gap_pct=gap_pct,
|
||||
cumulative_volume=int(cum_volume),
|
||||
relative_volume=rvol,
|
||||
|
||||
Reference in new issue
Block a user