@@ -438,55 +438,78 @@ func (t *AsterTrader) GetBalance() (map[string]interface{}, error) {
438438 return nil , err
439439 }
440440
441- // 🔍 调试:打印原始API响应
442- log .Printf ("🔍 Aster API原始响应: %s" , string (body ))
443-
444441 // 查找USDT余额
445- totalBalance := 0.0
446442 availableBalance := 0.0
447443 crossUnPnl := 0.0
444+ crossWalletBalance := 0.0
445+ foundUSDT := false
448446
449447 for _ , bal := range balances {
450- // 🔍 调试:打印每条余额记录
451- log .Printf ("🔍 余额记录: %+v" , bal )
452-
453448 if asset , ok := bal ["asset" ].(string ); ok && asset == "USDT" {
454- // 🔍 调试:打印USDT余额详情
455- log .Printf ("🔍 USDT余额详情: balance=%v, availableBalance=%v, crossUnPnl=%v" ,
456- bal ["balance" ], bal ["availableBalance" ], bal ["crossUnPnl" ])
449+ foundUSDT = true
457450
458- if wb , ok := bal ["balance" ].(string ); ok {
459- totalBalance , _ = strconv .ParseFloat (wb , 64 )
460- }
451+ // 解析Aster字段(参考: https://github.com/asterdex/api-docs)
461452 if avail , ok := bal ["availableBalance" ].(string ); ok {
462453 availableBalance , _ = strconv .ParseFloat (avail , 64 )
463454 }
464455 if unpnl , ok := bal ["crossUnPnl" ].(string ); ok {
465456 crossUnPnl , _ = strconv .ParseFloat (unpnl , 64 )
466457 }
458+ if cwb , ok := bal ["crossWalletBalance" ].(string ); ok {
459+ crossWalletBalance , _ = strconv .ParseFloat (cwb , 64 )
460+ }
467461 break
468462 }
469463 }
470464
471- // ✅ Aster API完全兼容Binance API格式
472- // balance字段 = wallet balance(不包含未实现盈亏)
473- // crossUnPnl = unrealized profit(未实现盈亏)
474- // crossWalletBalance = balance + crossUnPnl(全仓钱包余额,包含盈亏)
475- //
476- // 参考Binance官方文档:
477- // - Account Information V2: marginBalance = walletBalance + unrealizedProfit
478- // - Balance V3: crossWalletBalance = balance + crossUnPnl
465+ if ! foundUSDT {
466+ log .Printf ("⚠️ 未找到USDT资产记录!" )
467+ }
468+
469+ // 获取持仓计算保证金占用和真实未实现盈亏
470+ positions , err := t .GetPositions ()
471+ if err != nil {
472+ log .Printf ("⚠️ 获取持仓信息失败: %v" , err )
473+ // fallback: 无法获取持仓时使用简单计算
474+ return map [string ]interface {}{
475+ "totalWalletBalance" : crossWalletBalance ,
476+ "availableBalance" : availableBalance ,
477+ "totalUnrealizedProfit" : crossUnPnl ,
478+ }, nil
479+ }
480+
481+ // ⚠️ 关键修复:从持仓中累加真正的未实现盈亏
482+ // Aster 的 crossUnPnl 字段不准确,需要从持仓数据中重新计算
483+ totalMarginUsed := 0.0
484+ realUnrealizedPnl := 0.0
485+ for _ , pos := range positions {
486+ markPrice := pos ["markPrice" ].(float64 )
487+ quantity := pos ["positionAmt" ].(float64 )
488+ if quantity < 0 {
489+ quantity = - quantity
490+ }
491+ unrealizedPnl := pos ["unRealizedProfit" ].(float64 )
492+ realUnrealizedPnl += unrealizedPnl
493+
494+ leverage := 10
495+ if lev , ok := pos ["leverage" ].(float64 ); ok {
496+ leverage = int (lev )
497+ }
498+ marginUsed := (quantity * markPrice ) / float64 (leverage )
499+ totalMarginUsed += marginUsed
500+ }
479501
480- log .Printf ("✓ Aster API返回: 钱包余额=%.2f, 未实现盈亏=%.2f, 可用余额=%.2f" ,
481- totalBalance ,
482- crossUnPnl ,
483- availableBalance )
502+ // ✅ Aster 正确计算方式:
503+ // 总净值 = 可用余额 + 保证金占用
504+ // 钱包余额 = 总净值 - 未实现盈亏
505+ // 未实现盈亏 = 从持仓累加计算(不使用API的crossUnPnl)
506+ totalEquity := availableBalance + totalMarginUsed
507+ totalWalletBalance := totalEquity - realUnrealizedPnl
484508
485- // 返回与Binance相同的字段名,确保AutoTrader能正确解析
486509 return map [string ]interface {}{
487- "totalWalletBalance" : totalBalance , // 钱包余额(不含未实现盈亏)
488- "availableBalance" : availableBalance ,
489- "totalUnrealizedProfit" : crossUnPnl , // 未实现盈亏
510+ "totalWalletBalance" : totalWalletBalance , // 钱包余额(不含未实现盈亏)
511+ "availableBalance" : availableBalance , // 可用余额
512+ "totalUnrealizedProfit" : realUnrealizedPnl , // 未实现盈亏(从持仓累加)
490513 }, nil
491514}
492515
@@ -1010,8 +1033,6 @@ func (t *AsterTrader) SetTakeProfit(symbol string, positionSide string, quantity
10101033 return err
10111034}
10121035
1013-
1014-
10151036// CancelStopLossOrders 仅取消止损单(不影响止盈单)
10161037func (t * AsterTrader ) CancelStopLossOrders (symbol string ) error {
10171038 // 获取该币种的所有未完成订单
0 commit comments