diff --git a/frontend/console.html b/frontend/console.html index 7c2ac82..78684cd 100644 --- a/frontend/console.html +++ b/frontend/console.html @@ -975,6 +975,91 @@ gap: 10px; } + .signal-feed-grid { + display: grid; + gap: 12px; + } + + .signal-feed-card { + padding: 14px 16px; + border-radius: 16px; + background: rgba(255,255,255,0.03); + border: 1px solid rgba(255,255,255,0.06); + } + + .signal-feed-card.buy { + border-color: rgba(48, 209, 88, 0.18); + background: rgba(48, 209, 88, 0.07); + } + + .signal-feed-card.sell { + border-color: rgba(255, 111, 97, 0.18); + background: rgba(255, 111, 97, 0.07); + } + + .signal-feed-head { + display: flex; + justify-content: space-between; + gap: 12px; + align-items: flex-start; + margin-bottom: 10px; + } + + .signal-feed-symbol { + font-size: 16px; + font-weight: 700; + color: var(--text); + } + + .signal-feed-meta { + color: var(--muted); + font-size: 11px; + font-family: "IBM Plex Mono", monospace; + line-height: 1.5; + } + + .signal-feed-tags { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-bottom: 10px; + } + + .signal-feed-stats { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; + margin-bottom: 10px; + } + + .signal-feed-stat { + padding: 10px 12px; + border-radius: 12px; + background: rgba(255,255,255,0.03); + } + + .signal-feed-stat .label { + display: block; + color: var(--muted); + font-size: 10px; + margin-bottom: 4px; + text-transform: uppercase; + letter-spacing: 0.05em; + font-family: "IBM Plex Mono", monospace; + } + + .signal-feed-stat .value { + font-family: "IBM Plex Mono", monospace; + font-size: 13px; + color: var(--text); + } + + .signal-feed-reason { + color: var(--muted); + font-size: 12px; + line-height: 1.65; + } + .workspace-stream { min-height: 0; } @@ -1673,6 +1758,101 @@ background: rgba(255,255,255,0.02); } + .position-card-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 14px; + } + + .position-card { + padding: 16px; + border-radius: 18px; + background: rgba(255,255,255,0.03); + border: 1px solid rgba(255,255,255,0.06); + } + + .position-card.long { + border-color: rgba(48, 209, 88, 0.18); + } + + .position-card.short { + border-color: rgba(255, 111, 97, 0.18); + } + + .position-card-head { + display: flex; + justify-content: space-between; + gap: 12px; + align-items: flex-start; + margin-bottom: 12px; + } + + .position-card-symbol { + font-size: 16px; + font-weight: 700; + color: var(--text); + } + + .position-card-meta { + color: var(--muted); + font-size: 11px; + font-family: "IBM Plex Mono", monospace; + line-height: 1.5; + } + + .position-card-pnl { + text-align: right; + } + + .position-card-pnl .amount { + font-family: "IBM Plex Mono", monospace; + font-size: 18px; + font-weight: 600; + } + + .position-card-pnl .ratio { + margin-top: 4px; + font-family: "IBM Plex Mono", monospace; + font-size: 12px; + } + + .position-card-gridline { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; + margin-bottom: 12px; + } + + .position-card-block { + padding: 10px 12px; + border-radius: 12px; + background: rgba(255,255,255,0.03); + } + + .position-card-block .label { + display: block; + color: var(--muted); + font-size: 10px; + margin-bottom: 4px; + text-transform: uppercase; + letter-spacing: 0.05em; + font-family: "IBM Plex Mono", monospace; + } + + .position-card-block .value { + font-family: "IBM Plex Mono", monospace; + font-size: 13px; + color: var(--text); + line-height: 1.55; + } + + .position-card-tags { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-bottom: 10px; + } + .unified-table table { min-width: 980px; } @@ -1771,12 +1951,15 @@ .platform-grid, .signal-grid, .ops-grid, - .coord-grid { + .coord-grid, + .position-card-grid { grid-template-columns: 1fr; } .platform-overview, - .platform-stats { + .platform-stats, + .signal-feed-stats, + .position-card-gridline { grid-template-columns: repeat(2, minmax(0, 1fr)); } @@ -1807,6 +1990,8 @@ .hero-metrics, .platform-stats, .platform-overview, + .signal-feed-stats, + .position-card-gridline, .signal-stats, .heartbeat-grid, .health-ribbon, @@ -2817,17 +3002,46 @@ return; } - container.innerHTML = signals.map((signal) => ` -
-
${relativeTime(signal.created_at)}
${formatTime(signal.created_at)}
-
- ${signal.symbol || '-'} - ${signal.action === 'buy' ? '做多' : signal.action === 'sell' ? '做空' : '观望'} - | ${signal.signal_type || '-'} | ${signal.timeframe || signal.type || '-'} -
-
${signal.grade || '-'} / ${formatPercent(signal.confidence || 0, 1)}
+ container.innerHTML = ` +
+ ${signals.slice(0, 5).map((signal) => ` +
+
+
+
${signal.symbol || '-'}
+
${relativeTime(signal.created_at)} / ${formatTime(signal.created_at)}
+
+ ${signal.action === 'buy' ? '做多' : signal.action === 'sell' ? '做空' : '观望'} +
+
+ ${signal.signal_type || '-'} + ${signal.timeframe || signal.type || '-'} + ${signal.grade ? `${signal.grade}` : ''} + ${signal.setup_type ? `${signal.setup_type}` : ''} +
+
+
+ 信心度 + ${formatPercent(signal.confidence || 0, 1)} +
+
+ 价格 + 入场 ${formatMoney(signal.entry_price)} / 现价 ${formatMoney(signal.current_price)} +
+
+ 止盈止损 + ${formatMoney(signal.take_profit)} / ${formatMoney(signal.stop_loss)} +
+
+ 仓位 / 入场方式 + ${signal.position_size || '-'} / ${signal.entry_type || '-'} +
+
+
${signal.reasoning || signal.reason || signal.summary || '暂无详细分析理由'}
+
+ `).join('')}
- `).join(''); + `; } function renderAgentSignals(cryptoAgent, signalStats) { @@ -3280,40 +3494,45 @@ } container.innerHTML = ` - - - - - - - - - - - - - - - - - - ${total.map((item) => ` - - - - - - - - - - - - - - `).join('')} - -
平台账号交易对方向入场 / 现价仓位 / 杠杆Setup止盈 / 止损未实现盈亏盈亏比例时间
${item.platform}${item.account_id || '-'}${item.symbol || '-'}${item.side === 'long' ? 'long' : 'short'}${formatMoney(item.entry_price)} / ${formatMoney(item.mark_price)}${formatNumber(item.size, 4)} / ${formatNumber(item.leverage, 1)}x${item.setup_type ? `
${item.setup_type}
${item.entry_basis || item.setup_basis || '-'}
` : '-'}
${item.take_profit ? formatMoney(item.take_profit) : '-'} / ${item.stop_loss ? formatMoney(item.stop_loss) : '-'}${formatMoney(item.unrealized_pnl)}${formatPercent(item.pnl_percent, 2)}${item.opened_at ? relativeTime(item.opened_at) : '-'}
+
+ ${total.map((item) => ` +
+
+
+
${item.symbol || '-'}
+
${item.platform || '-'} / ${item.account_id || '-'} / ${item.opened_at ? `${relativeTime(item.opened_at)} / ${formatTime(item.opened_at)}` : '-'}
+
+
+
${formatMoney(item.unrealized_pnl)}
+
${formatPercent(item.pnl_percent, 2)}
+
+
+
+ ${item.platform} + ${item.side === 'long' ? 'long' : 'short'} + ${item.setup_type ? `${item.setup_type}` : ''} +
+
+
+ 入场 / 现价 + ${formatMoney(item.entry_price)} / ${formatMoney(item.mark_price)} +
+
+ 仓位 / 杠杆 + ${formatNumber(item.size, 4)} / ${formatNumber(item.leverage, 1)}x +
+
+ 止盈 / 止损 + ${item.take_profit ? formatMoney(item.take_profit) : '-'} / ${item.stop_loss ? formatMoney(item.stop_loss) : '-'} +
+
+ Setup / Entry + ${item.setup_type || '-'}${item.entry_basis || item.setup_basis ? `
${item.entry_basis || item.setup_basis}` : ''}
+
+
+
+ `).join('')} +
`; }