diff --git a/frontend/app/paper-v53/page.tsx b/frontend/app/paper-v53/page.tsx index a179763..2ffaaf2 100644 --- a/frontend/app/paper-v53/page.tsx +++ b/frontend/app/paper-v53/page.tsx @@ -37,6 +37,100 @@ const STRATEGY_LABELS: Record>({}); + + useEffect(() => { + const f = async () => { + for (const sym of coins) { + const coin = sym.replace("USDT", ""); + const strat = strategy === "v53_btc" ? "v53_btc" : "v53_alt"; + try { + const r = await authFetch(`/api/signals/signal-history?symbol=${coin}&limit=1&strategy=${strat}`); + if (r.ok) { + const j = await r.json(); + if (j.data && j.data.length > 0) setSignals(prev => ({ ...prev, [sym]: j.data[0] })); + } + } catch {} + } + }; + f(); + const iv = setInterval(f, 15000); + return () => clearInterval(iv); + }, [strategy, coins]); + + const meta = STRATEGY_LABELS[strategy]; + + return ( +
+
+

最新信号

+ {strategy} +
+
+ {coins.map(sym => { + const s = signals[sym]; + const coin = sym.replace("USDT", ""); + const ago = s?.ts ? Math.round((Date.now() - s.ts) / 60000) : null; + const fc = s?.factors; + return ( +
+
+
+ {coin} + {s?.signal ? ( + <> + + {s.signal === "LONG" ? "🟢" : "🔴"} {s.signal} + + {s.score}分 + + {s.score >= 85 ? "加仓" : s.score >= 75 ? "标准" : "观望"} + + + ) : ( + 暂无信号 + )} +
+ {ago !== null && ( + {ago < 60 ? `${ago}m前` : `${Math.round(ago / 60)}h前`} + )} +
+ {fc && strategy === "v53_alt" && ( +
+ 方向{fc.direction?.score ?? 0}/55 + 拥挤{fc.crowding?.score ?? 0}/25 + 环境{fc.environment?.score ?? 0}/15 + 辅助{fc.auxiliary?.score ?? 0}/5 +
+ )} + {fc && strategy === "v53_btc" && ( +
+ + {fc.gate_passed ? "✅ Gate通过" : "❌ Gate否决"} + + {fc.block_reason && ( + {fc.block_reason} + )} + + OBI {((fc.obi_raw ?? 0) * 100).toFixed(2)}% + +
+ )} +
+ ); + })} +
+
+ ); +} + // ─── 控制面板 ──────────────────────────────────────────────────── function ControlPanel() { @@ -432,6 +526,7 @@ export default function PaperTradingV53Page() { +