Skip to content

Commit ad3d6b9

Browse files
the-dev-zclaude
andcommitted
fix(trader): fix auto balance sync using totalEquity instead of availableBalance
修复 autoSyncBalanceIfNeeded() 的严重 bug: 问题: - 旧逻辑使用 availableBalance 检测余额变化 - 当持有仓位时,availableBalance 会因保证金占用而减少 - 导致误判为"余额下降"并错误更新 initialBalance 示例场景: 1. initialBalance = 1000 USDT (total equity) 2. 开多单盈利 +100 → totalEquity = 1100, availableBalance = 900 (保证金占用) 3. 自动检查触发:(900 - 1000) / 1000 = -10% > 5% 阈值 4. 错误更新:initialBalance 从 1000 改成 900 ❌ 5. 平仓后 P&L 计算彻底错误 修复: ✅ 使用 totalEquity = totalWalletBalance + totalUnrealizedProfit ✅ 准确反映账户真实价值,不受持仓影响 ✅ 保留 availableBalance 作为 fallback ✅ 保持 5% 变化阈值(合理) ✅ 增强日志:显示钱包余额和未实现盈亏明细 影响范围: - 自动余额同步机制(每 10 分钟检查一次) - 所有交易所(Binance, Hyperliquid, Aster) 相关: - 之前有人建议改成 > 50000 作为 workaround(禁用自动同步) - 本次修复从根本上解决问题,无需修改阈值 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent f3a0fa6 commit ad3d6b9

File tree

1 file changed

+30
-13
lines changed

1 file changed

+30
-13
lines changed

trader/auto_trader.go

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -303,18 +303,35 @@ func (at *AutoTrader) autoSyncBalanceIfNeeded() {
303303
return
304304
}
305305

306-
// 提取可用余额
306+
// ✅ 提取总资产(total equity = 钱包余额 + 未实现盈亏)
307+
// 使用总资产而不是可用余额,避免持仓时误判余额变化
307308
var actualBalance float64
308-
if availableBalance, ok := balanceInfo["available_balance"].(float64); ok && availableBalance > 0 {
309-
actualBalance = availableBalance
310-
} else if availableBalance, ok := balanceInfo["availableBalance"].(float64); ok && availableBalance > 0 {
311-
actualBalance = availableBalance
312-
} else if totalBalance, ok := balanceInfo["balance"].(float64); ok && totalBalance > 0 {
313-
actualBalance = totalBalance
309+
totalWalletBalance := 0.0
310+
totalUnrealizedProfit := 0.0
311+
312+
if wallet, ok := balanceInfo["totalWalletBalance"].(float64); ok {
313+
totalWalletBalance = wallet
314+
}
315+
if unrealized, ok := balanceInfo["totalUnrealizedProfit"].(float64); ok {
316+
totalUnrealizedProfit = unrealized
317+
}
318+
319+
totalEquity := totalWalletBalance + totalUnrealizedProfit
320+
if totalEquity > 0 {
321+
actualBalance = totalEquity
314322
} else {
315-
log.Printf("⚠️ [%s] 无法提取可用余额", at.name)
316-
at.lastBalanceSyncTime = time.Now()
317-
return
323+
// Fallback: 尝试其他字段
324+
if availableBalance, ok := balanceInfo["availableBalance"].(float64); ok && availableBalance > 0 {
325+
actualBalance = availableBalance
326+
log.Printf("⚠️ [%s] 无法提取 totalEquity,使用 availableBalance: %.2f", at.name, actualBalance)
327+
} else if balance, ok := balanceInfo["balance"].(float64); ok && balance > 0 {
328+
actualBalance = balance
329+
log.Printf("⚠️ [%s] 无法提取 totalEquity,使用 balance: %.2f", at.name, actualBalance)
330+
} else {
331+
log.Printf("⚠️ [%s] 无法提取任何余额字段", at.name)
332+
at.lastBalanceSyncTime = time.Now()
333+
return
334+
}
318335
}
319336

320337
oldBalance := at.initialBalance
@@ -347,8 +364,8 @@ func (at *AutoTrader) autoSyncBalanceIfNeeded() {
347364

348365
// 变化超过5%才更新
349366
if math.Abs(changePercent) > 5.0 {
350-
log.Printf("🔔 [%s] 检测到余额大幅变化: %.2f → %.2f USDT (%.2f%%)",
351-
at.name, oldBalance, actualBalance, changePercent)
367+
log.Printf("🔔 [%s] 检测到余额大幅变化: %.2f → %.2f USDT (%.2f%%) [钱包: %.2f + 未实现: %.2f]",
368+
at.name, oldBalance, actualBalance, changePercent, totalWalletBalance, totalUnrealizedProfit)
352369

353370
// 更新内存中的 initialBalance
354371
at.initialBalance = actualBalance
@@ -375,7 +392,7 @@ func (at *AutoTrader) autoSyncBalanceIfNeeded() {
375392
log.Printf("⚠️ [%s] 数据库引用为空,余额仅在内存中更新", at.name)
376393
}
377394
} else {
378-
log.Printf("✓ [%s] 余额变化不大 (%.2f%%),无需更新", at.name, changePercent)
395+
log.Printf("✓ [%s] 余额变化不大 (%.2f%%),无需更新 [当前总资产: %.2f USDT]", at.name, changePercent, actualBalance)
379396
}
380397

381398
at.lastBalanceSyncTime = time.Now()

0 commit comments

Comments
 (0)