From 374615dea749e4cdc75d8ff5075b833ce3879012 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 28 Feb 2026 12:45:47 +0000 Subject: [PATCH] feat: paper page show latest signal per coin --- frontend/app/paper/page.tsx | 56 +++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/frontend/app/paper/page.tsx b/frontend/app/paper/page.tsx index e142fb4..5a514ae 100644 --- a/frontend/app/paper/page.tsx +++ b/frontend/app/paper/page.tsx @@ -108,6 +108,61 @@ function SummaryCards() { ); } +// ─── 最新信号状态 ──────────────────────────────────────────────── + +const COINS = ["BTCUSDT", "ETHUSDT", "XRPUSDT", "SOLUSDT"]; + +function LatestSignals() { + const [signals, setSignals] = useState>({}); + useEffect(() => { + const f = async () => { + for (const sym of COINS) { + try { + const r = await authFetch(`/api/signals/latest?symbol=${sym}`); + if (r.ok) { + const j = await r.json(); + setSignals(prev => ({ ...prev, [sym]: j })); + } + } catch {} + } + }; + f(); const iv = setInterval(f, 15000); return () => clearInterval(iv); + }, []); + + return ( +
+
+

最新信号

+
+
+ {COINS.map(sym => { + const s = signals[sym]; + const coin = sym.replace("USDT", ""); + const ago = s?.ts ? Math.round((Date.now() - s.ts) / 60000) : null; + return ( +
+
+ {coin} + {s?.signal ? ( + <> + + {s.signal === "LONG" ? "🟢" : "🔴"} {s.signal} + + {s.score}分 + + ) : ( + ⚪ 无信号 + )} +
+ {ago !== null && {ago < 60 ? `${ago}m前` : `${Math.round(ago/60)}h前`}} +
+ ); + })} +
+
+ ); +} + // ─── 当前持仓 ──────────────────────────────────────────────────── function ActivePositions() { @@ -378,6 +433,7 @@ export default function PaperTradingPage() { +