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) => ` -
| 平台 | -账号 | -交易对 | -方向 | -入场 / 现价 | -仓位 / 杠杆 | -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) : '-'} | -