Phase 3: Real-time enhancements
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
This commit is contained in:
@@ -63,6 +63,8 @@ type Trader struct {
|
||||
positions map[string]*ArbPosition // coin -> position
|
||||
lastTradeTime map[string]time.Time
|
||||
closedTrades []TradeRecord // history of closed trades
|
||||
|
||||
OnTradeEvent func(event string, data interface{}) // P3-4: real-time SSE push
|
||||
}
|
||||
|
||||
// TradeRecord stores a finalized trade for stats tracking.
|
||||
@@ -277,6 +279,17 @@ func (t *Trader) executeEntry(opp *ArbOpportunity, store *PriceStore, notifier *
|
||||
pos.LongLeg.Exchange, pos.LongLeg.EntryPrice,
|
||||
pos.ShortLeg.Exchange, pos.ShortLeg.EntryPrice,
|
||||
diff, t.cfg.TradeAmountUSD))
|
||||
|
||||
// P3-4: real-time trade event push
|
||||
if t.OnTradeEvent != nil {
|
||||
t.OnTradeEvent("trade_open", map[string]interface{}{
|
||||
"coin": pos.Coin,
|
||||
"direction": pos.Direction,
|
||||
"entry_spread": diff,
|
||||
"amount_usd": t.cfg.TradeAmountUSD,
|
||||
"time": time.Now().Format("15:04:05"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// checkScaleIn adds more position when spread widens further.
|
||||
@@ -432,6 +445,20 @@ func (t *Trader) checkExit(pos *ArbPosition, bgP, hlP, diffPct float64, notifier
|
||||
msg += fmt.Sprintf(" 平仓异常: %s\n", closeErr)
|
||||
}
|
||||
notifier.Send(msg)
|
||||
|
||||
// P3-4: real-time trade event push
|
||||
if t.OnTradeEvent != nil {
|
||||
t.OnTradeEvent("trade_close", map[string]interface{}{
|
||||
"coin": pos.Coin,
|
||||
"direction": pos.Direction,
|
||||
"entry_spread": pos.EntrySpread,
|
||||
"exit_spread": diffPct,
|
||||
"pnl_pct": netPnl,
|
||||
"convergence": convergenceLabel,
|
||||
"duration": elapsed.Round(time.Second).String(),
|
||||
"time": time.Now().Format("15:04:05"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Trader) placeOrder(leg *PositionLeg, side string, store *PriceStore) string {
|
||||
|
||||
Reference in New Issue
Block a user