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: