diff --git a/ChanMacro/chan_integration.py b/ChanMacro/chan_integration.py index 370d00c..5d619c3 100644 --- a/ChanMacro/chan_integration.py +++ b/ChanMacro/chan_integration.py @@ -145,10 +145,26 @@ class ChanSignalDetector: logger.warning("未检测到任何 BSP 信号") return 0 - # Step 2: 写入 signal_features(含市场状态和 forward outcomes) + # Step 2: 去重 — 跳过已存在的信号 + from database import get_connection + conn = get_connection() + existing = set() + for row in conn.execute( + "SELECT date, signal_type FROM signal_features" + ).fetchall(): + existing.add((row[0], row[1])) + conn.close() + + new_signals = [s for s in signals + if (str(s["date"]), s["signal_type"]) not in existing] + if not new_signals: + logger.info("所有信号已存在,跳过") + return 0 + + # Step 3: 写入 signal_features from expectancy.tracker import SignalTracker tracker = SignalTracker() - count = tracker.backfill_signals(signals) + count = tracker.backfill_signals(new_signals) logger.info(f"信号入库完成: {count}/{len(signals)}") return count diff --git a/ChanMacro/scheduler.py b/ChanMacro/scheduler.py index c6b3646..702f524 100644 --- a/ChanMacro/scheduler.py +++ b/ChanMacro/scheduler.py @@ -115,7 +115,23 @@ class MacroScheduler: conn.commit() conn.close() - self._last_run = datetime.now(timezone.utc) + # 检测新信号(每天运行一次,UTC 0 点后首次触发) + now = datetime.now(timezone.utc) + if self._last_run is None or now.date() > self._last_run.date(): + try: + from chan_integration import ChanSignalDetector + detector = ChanSignalDetector() + # 检测最近 90 天的 4h 信号 + count = detector.populate_signal_features( + start_date=(today - __import__('datetime').timedelta(days=90)).isoformat(), + end_date=today.isoformat(), + ) + if count > 0: + logger.info(f"新增 {count} 条信号记录") + except Exception as e: + logger.debug(f"信号检测跳过: {e}") + + self._last_run = now logger.info( f"Tick 完成: regime={r.regime.value} conf={r.confidence:.2f} " f"breadth={br.score:.0f}({br.breadth_bucket.value}) "