From 05673c0850e80cffffb83f1d0d50090d9905c5ce Mon Sep 17 00:00:00 2001 From: root Date: Mon, 2 Mar 2026 00:34:22 +0000 Subject: [PATCH] fix: V5.2 scoring uses strategy weights, total capped at 100 Backend: - Each layer score scaled by strategy config weights - direction: 0~40, crowding: 0~18, FR: 0~5, environment: 0~12 - confirmation: 0~15, liquidation: 0~5, auxiliary: 0~5 - total_score clamped to 0~100 - factors include max field for frontend Frontend: - V5.2 signals page reads max from factors --- backend/signal_engine.py | 41 +++++++++++++++++++++++++------ frontend/app/signals-v52/page.tsx | 28 ++++++++++----------- signal-engine.log | 15 +++++++++++ 3 files changed, 62 insertions(+), 22 deletions(-) diff --git a/backend/signal_engine.py b/backend/signal_engine.py index 16c4529..a5724fb 100644 --- a/backend/signal_engine.py +++ b/backend/signal_engine.py @@ -556,24 +556,49 @@ class SymbolState: else: aux_score = 0 - total_score = direction_score + accel_bonus + crowding_score + fr_score + environment_score + confirmation_score + liq_score + aux_score + # 按策略配置的权重缩放各层分数 + weights = strategy_cfg.get("weights", {}) + w_direction = weights.get("direction", 45) + w_crowding = weights.get("crowding", 20) + w_fr = weights.get("funding_rate", 0) + w_environment = weights.get("environment", 15) + w_confirmation = weights.get("confirmation", 15) + w_liq = weights.get("liquidation", 0) + w_auxiliary = weights.get("auxiliary", 5) + + # 原始评分范围: direction 0~45, crowding 0~20, environment 0~15, confirmation 0~15, auxiliary 0~5 + # FR 0~5 (or -5~5), Liq 0~5 + # 缩放到配置权重 + scaled_direction = round(direction_score / 45 * w_direction) + accel_bonus + scaled_crowding = round(crowding_score / 20 * w_crowding) + scaled_fr = fr_score if w_fr > 0 else 0 # FR already 0~5 range, matches w_fr=5 + scaled_environment = round(environment_score / 15 * w_environment) + scaled_confirmation = round(confirmation_score / 15 * w_confirmation) + scaled_liq = liq_score if w_liq > 0 else 0 # Liq already 0~5 range, matches w_liq=5 + scaled_auxiliary = round(aux_score / 5 * w_auxiliary) + + total_score = scaled_direction + scaled_crowding + scaled_fr + scaled_environment + scaled_confirmation + scaled_liq + scaled_auxiliary + total_score = max(0, min(total_score, 100)) # clamp 0~100 + result["score"] = total_score result["direction"] = direction result["factors"] = { "direction": { - "score": direction_score, + "score": scaled_direction, + "max": w_direction, "cvd_fast": 15 if ((direction == "LONG" and cvd_fast > 0) or (direction == "SHORT" and cvd_fast < 0)) else 0, "cvd_mid": 15 if ((direction == "LONG" and cvd_mid > 0) or (direction == "SHORT" and cvd_mid < 0)) else 0, "p99_flow": 15 if has_aligned_p99 else (10 if not has_adverse_p99 else 0), "accel_bonus": accel_bonus, }, - "crowding": {"score": crowding_score, "long_short_ratio": ls_score, "top_trader_position": top_trader_score}, - "environment": {"score": environment_score, "open_interest_hist": oi_change}, - "confirmation": {"score": confirmation_score}, - "auxiliary": {"score": aux_score, "coinbase_premium": coinbase_premium}, - "funding_rate": {"score": fr_score, "value": funding_rate}, + "crowding": {"score": scaled_crowding, "max": w_crowding, "long_short_ratio": ls_score, "top_trader_position": top_trader_score}, + "environment": {"score": scaled_environment, "max": w_environment, "open_interest_hist": oi_change}, + "confirmation": {"score": scaled_confirmation, "max": w_confirmation}, + "auxiliary": {"score": scaled_auxiliary, "max": w_auxiliary, "coinbase_premium": coinbase_premium}, + "funding_rate": {"score": scaled_fr, "max": w_fr, "value": funding_rate}, "liquidation": { - "score": liq_score, + "score": scaled_liq, + "max": w_liq, "long_usd": liq_data.get("long_usd", 0) if liq_data else 0, "short_usd": liq_data.get("short_usd", 0) if liq_data else 0, }, diff --git a/frontend/app/signals-v52/page.tsx b/frontend/app/signals-v52/page.tsx index 778c4c7..c81acfb 100644 --- a/frontend/app/signals-v52/page.tsx +++ b/frontend/app/signals-v52/page.tsx @@ -39,13 +39,13 @@ interface LatestIndicator { signal: string | null; tier?: "light" | "standard" | "heavy" | null; factors?: { - direction?: { score?: number }; - crowding?: { score?: number }; - environment?: { score?: number }; - confirmation?: { score?: number }; - auxiliary?: { score?: number }; - funding_rate?: { score?: number; value?: number }; - liquidation?: { score?: number; long_usd?: number; short_usd?: number }; + direction?: { score?: number; max?: number }; + crowding?: { score?: number; max?: number }; + environment?: { score?: number; max?: number }; + confirmation?: { score?: number; max?: number }; + auxiliary?: { score?: number; max?: number }; + funding_rate?: { score?: number; max?: number; value?: number }; + liquidation?: { score?: number; max?: number; long_usd?: number; short_usd?: number }; } | null; } @@ -325,13 +325,13 @@ function IndicatorCards({ symbol }: { symbol: Symbol }) {
- - - - - - - + + + + + + +
diff --git a/signal-engine.log b/signal-engine.log index 1468f05..22bf754 100644 --- a/signal-engine.log +++ b/signal-engine.log @@ -109,3 +109,18 @@ 2026-03-02 00:22:37,395 [INFO] signal-engine: [XRPUSDT] 🚨 信号[v52_8signals]: LONG score=77 price=1.4 2026-03-02 00:23:08,756 [INFO] signal-engine: [ETHUSDT] 🚨 信号[v51_baseline]: LONG score=85 price=1943.5 2026-03-02 00:23:08,756 [INFO] signal-engine: [ETHUSDT] 🚨 信号[v52_8signals]: LONG score=90 price=1943.5 +2026-03-02 00:25:13,809 [INFO] signal-engine: 已加载策略配置: v51_baseline, v52_8signals +2026-03-02 00:25:17,084 [INFO] signal-engine: [BTCUSDT] 冷启动完成: 加载467,836条历史数据 (窗口=4h) +2026-03-02 00:25:20,192 [INFO] signal-engine: [ETHUSDT] 冷启动完成: 加载457,043条历史数据 (窗口=4h) +2026-03-02 00:25:20,634 [INFO] signal-engine: [XRPUSDT] 冷启动完成: 加载65,387条历史数据 (窗口=4h) +2026-03-02 00:25:21,081 [INFO] signal-engine: [SOLUSDT] 冷启动完成: 加载67,363条历史数据 (窗口=4h) +2026-03-02 00:25:21,081 [INFO] signal-engine: === Signal Engine (PG) 启动完成 === +2026-03-02 00:25:21,333 [INFO] signal-engine: [BTCUSDT] 🚨 信号[v51_baseline]: LONG score=90 price=65913.4 +2026-03-02 00:25:21,334 [INFO] signal-engine: [BTCUSDT] 🚨 信号[v52_8signals]: LONG score=90 price=65913.4 +2026-03-02 00:25:21,612 [INFO] signal-engine: [ETHUSDT] 🚨 信号[v51_baseline]: LONG score=90 price=1943.7 +2026-03-02 00:25:21,612 [INFO] signal-engine: [ETHUSDT] 🚨 信号[v52_8signals]: LONG score=90 price=1943.7 +2026-03-02 00:25:21,693 [INFO] signal-engine: [XRPUSDT] 🚨 信号[v51_baseline]: LONG score=87 price=1.4 +2026-03-02 00:25:21,693 [INFO] signal-engine: [XRPUSDT] 🚨 信号[v52_8signals]: LONG score=82 price=1.4 +2026-03-02 00:25:21,780 [INFO] signal-engine: [SOLUSDT] 🚨 信号[v51_baseline]: LONG score=92 price=83.8 +2026-03-02 00:25:21,780 [INFO] signal-engine: [SOLUSDT] 🚨 信号[v52_8signals]: LONG score=87 price=83.8 +2026-03-02 00:25:53,073 [INFO] signal-engine: 冷启动保护期结束,模拟盘开仓已启用