From 2aa9f48ea39840de9fd671aa3e6b065fea88298a Mon Sep 17 00:00:00 2001 From: gahusb Date: Sun, 17 May 2026 13:35:29 +0900 Subject: [PATCH] feat(signal_v2-phase4): add emit/skip logging to signal_generator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit logger was declared but unused. Operational visibility was zero — trader debugging 'why no signal?' had to step through code mentally. - INFO on emit: '[signal emit] 005930 buy conf=0.823 rank=3' / sell with reason - DEBUG on each skip path: same-cycle sell, hard gate, low confidence, dedup 24h (buy and sell) Per final reviewer recommendation. 56 tests still pass. --- signal_v2/signal_generator.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/signal_v2/signal_generator.py b/signal_v2/signal_generator.py index fe24070..a37ce9a 100644 --- a/signal_v2/signal_generator.py +++ b/signal_v2/signal_generator.py @@ -32,16 +32,22 @@ def _evaluate_buy_signals(state, dedup, settings) -> None: for ticker, name, rank in candidates: existing = state.signals.get(ticker) if existing is not None and existing.get("action") == "sell": + logger.debug("buy %s skipped: same-cycle sell precedence", ticker) continue if not _check_buy_hard_gate(state, ticker, settings): + logger.debug("buy %s skipped: hard gate failed", ticker) continue confidence = _compute_buy_confidence(state, ticker, rank) if confidence <= settings.confidence_threshold: + logger.debug("buy %s skipped: confidence %.3f <= %.3f", + ticker, confidence, settings.confidence_threshold) continue if dedup.is_recent(ticker, "buy", within_hours=24): + logger.debug("buy %s skipped: dedup 24h", ticker) continue state.signals[ticker] = _build_buy_signal(state, ticker, name, rank, confidence) dedup.record(ticker, "buy", confidence=confidence) + logger.info("signal emit %s buy conf=%.3f rank=%s", ticker, confidence, rank) def _buy_candidates(state) -> list[tuple[str, str, int | None]]: @@ -122,9 +128,13 @@ def _evaluate_sell_signals(state, dedup, settings) -> None: if sell is None: continue if dedup.is_recent(ticker, "sell", within_hours=24): + logger.debug("sell %s skipped: dedup 24h", ticker) continue state.signals[ticker] = sell dedup.record(ticker, "sell", confidence=sell["confidence_webai"]) + logger.info("signal emit %s sell conf=%.3f reason=%s", + ticker, sell["confidence_webai"], + sell.get("context", {}).get("sell_reason")) def _try_stop_loss(state, holding: dict, settings) -> dict | None: