Bug: current spread always computed as (hl-bg)/bg regardless of
position direction. For HL→BG positions, spread should be (bg-hl)/hl
to match entry spread convention.
Fix: check LongLeg.Exchange — if HL→BG, use (bg-hl)/hl instead.
- Click any trade row in history table to open detail modal
- Modal shows 6 sections: 概览, 时间, 价差, 手续费, 多仓, 空仓
- Entries and exits displayed with 6 decimal precision
- Fee entry/exit and total fee displayed
- Open/close timestamps with full date-time format
- Duration, scale count, total amount, exit reason
- Orders sub-table if available
- Escape key and overlay click to close
P3-1: Scan optimization — only BG↔HL (50+ pair combos → 2)
P3-2: Real-time spread chart — spreadHistory ring buffer +
/api/spread-history endpoint + Chart.js spread chart
P3-3: Live position PnL — positions SSE now includes
estimated current profit/loss + current spread
P3-4: Real-time trade events — trader.OnTradeEvent callback
fires SSE 'trade_open' / 'trade_close' immediately
P3-5: Connection status monitoring — tracks last update time
per exchange, broadcast via stats.connections + /api/connections
Frontend: spread chart card, PnL column in positions,
connection status dots in stats bar,
green/red border flash on trade events