fix: armed trigger names now get watcher scoring (blank reasoning panels)
Four of ten armed triggers had NO criteria events ever — the trigger book arms from the live gapper scan while the watcher scores only the discovery watchlist, so scanner-only names (TCX/ZTG class) showed an empty reasoning panel with nothing behind it. - arm pass injects every complete armed candidate into the watchlist provider's extra_symbols (its standing manual-add hook) - provider returns injected symbols FIRST: the watcher truncates at max_symbols, so extras appended after a full research list were silently dropped — 'always include manually injected symbols' was untrue exactly when the list was full 60 watcher/watchlist/trigger tests pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
72a9ecbd0b
commit
37757d3d47
2 files changed
+31
-15
No files matched your search
@@ -55,10 +55,29 @@ class ResearchWatchlistProvider:
|
||||
price_max=self.price_max,
|
||||
limit=self.limit,
|
||||
)
|
||||
seen = set()
|
||||
# Injected symbols FIRST: the watcher truncates at max_symbols, so
|
||||
# extras appended after a full research list were silently dropped —
|
||||
# exactly the armed-trigger names the reasoning panel needs scored.
|
||||
candidates = []
|
||||
seen = set()
|
||||
for symbol in sorted(self.extra_symbols):
|
||||
seen.add(symbol)
|
||||
candidates.append(
|
||||
WatchCandidate(
|
||||
symbol=symbol,
|
||||
previous_close=research_query.query_previous_close(
|
||||
self.con, symbol, session_date
|
||||
),
|
||||
avg_daily_volume=research_query.query_avg_daily_volume(
|
||||
self.con, symbol, session_date
|
||||
),
|
||||
source="manual",
|
||||
)
|
||||
)
|
||||
for row in rows:
|
||||
symbol = row["symbol"]
|
||||
if symbol in seen:
|
||||
continue
|
||||
seen.add(symbol)
|
||||
candidates.append(
|
||||
WatchCandidate(
|
||||
@@ -73,20 +92,6 @@ class ResearchWatchlistProvider:
|
||||
source="research",
|
||||
)
|
||||
)
|
||||
# always include manually injected symbols
|
||||
for symbol in sorted(self.extra_symbols - seen):
|
||||
candidates.append(
|
||||
WatchCandidate(
|
||||
symbol=symbol,
|
||||
previous_close=research_query.query_previous_close(
|
||||
self.con, symbol, session_date
|
||||
),
|
||||
avg_daily_volume=research_query.query_avg_daily_volume(
|
||||
self.con, symbol, session_date
|
||||
),
|
||||
source="manual",
|
||||
)
|
||||
)
|
||||
return candidates
|
||||
|
||||
def get_bars(self, symbol: str, session_date: date) -> pd.DataFrame:
|
||||
|
||||
@@ -1016,6 +1016,17 @@ def main(argv: list[str] | None = None) -> int:
|
||||
# catalyst-backed gappers float to the top of the armed set
|
||||
candidates.sort(key=lambda c: c.get("_score", 0.0), reverse=True)
|
||||
book.arm(candidates)
|
||||
# Armed names must also get watcher scoring: the trigger book arms from
|
||||
# the live gapper scan, so names discovery never surfaced carried NO
|
||||
# criteria trail — 2026-08-01 four of ten armed rows had a blank
|
||||
# reasoning panel. extra_symbols is the provider's standing hook.
|
||||
try:
|
||||
_prov = rt["watcher"].provider
|
||||
for c in candidates:
|
||||
if c.get("symbol") and c.get("complete"):
|
||||
_prov.add_symbol(c["symbol"])
|
||||
except Exception: # noqa: BLE001 — observability aid, never blocks arming
|
||||
pass
|
||||
armed = sum(1 for t in book.triggers.values() if t.state == "armed")
|
||||
n_news = sum(1 for c in candidates if c.get("catalyst"))
|
||||
return f"tracking={len(book.triggers)} armed={armed}" + (f" news={n_news}" if n_news else "")
|
||||
|
||||
Reference in new issue
Block a user