fix: retryClose saves trade record and persists to DB on success

This commit is contained in:
jackyu66git
2026-05-03 23:19:15 +08:00
parent cf6548c37f
commit 68c0a342a6
+44 -2
View File
@@ -51,6 +51,15 @@ type ArbPosition struct {
RealizedPnl float64
ErrorLog string
// Exit metadata — saved when close is first attempted; reused by retryClose
ExitDiffPct float64 // spread % at exit trigger
ExitNetPnl float64 // net PnL % at exit trigger
ExitLongPnl float64 // long leg PnL %
ExitShortPnl float64 // short leg PnL %
ExitTotalFees float64 // total fee %
ExitConvergence string // convergence label
ExitReasonText string // reason for exit
// Track all entry prices for weighted-average PnL across scale-ins (Issue #2)
LongEntryPrices []float64 // all long entry prices (initial + scale-ins)
ShortEntryPrices []float64 // all short entry prices (initial + scale-ins)
@@ -534,6 +543,15 @@ func (t *Trader) checkExit(pos *ArbPosition, bgP, hlP, diffPct float64, notifier
pos.LongLeg.ExitPrice = longCurrent
pos.ShortLeg.ExitPrice = shortCurrent
// Save exit metadata for retryClose in case closeBothLegs fails
pos.ExitDiffPct = diffPct
pos.ExitNetPnl = netPnl
pos.ExitLongPnl = longPnl
pos.ExitShortPnl = shortPnl
pos.ExitTotalFees = totalFees
pos.ExitConvergence = convergenceLabel
pos.ExitReasonText = exitReason
closeErr := t.closeBothLegs(pos)
if closeErr != "" {
@@ -691,17 +709,41 @@ func (t *Trader) retryClose(pos *ArbPosition, bgP, hlP float64, notifier *Notifi
closeErr := t.closeBothLegs(pos)
if closeErr == "" {
// All legs finally closed — mark as done
// All legs finally closed — record + persist
pos.Status = "closed"
pos.ExitedAt = time.Now()
elapsed := time.Since(pos.StartedAt)
record := TradeRecord{
Coin: pos.Coin,
Direction: pos.Direction,
EntrySpread: pos.EntrySpread,
ExitSpread: pos.ExitDiffPct,
PnlPct: pos.ExitNetPnl,
Convergence: pos.ExitConvergence,
Reason: pos.ExitReasonText,
Duration: elapsed.Round(time.Second).String(),
OpenedAt: pos.StartedAt,
ClosedAt: pos.ExitedAt,
ScaleLevels: pos.ScaleLevels,
AmountUSD: pos.AmountUSD,
}
t.mu.Lock()
delete(t.positions, pos.Coin)
t.lastTradeTime[pos.Coin] = time.Now()
t.closedTrades = append(t.closedTrades, record)
t.mu.Unlock()
if t.db != nil {
t.persistTrade(pos, pos.ExitDiffPct, pos.ExitConvergence, pos.ExitReasonText,
pos.ExitNetPnl, pos.ExitLongPnl, pos.ExitShortPnl, pos.ExitTotalFees)
}
notifier.Send(fmt.Sprintf(
"<b>[平仓重试成功]</b> %s/USDT %s\n"+
" 之前失败: %s\n"+
" 已成功关掉所有腿\n", pos.Coin, pos.Direction, pos.ErrorLog))
" 已成功关掉所有腿 | 盈亏: %+.4f%%\n", pos.Coin, pos.Direction, pos.ErrorLog, pos.ExitNetPnl))
return
}