2026-05-07 09:56:21 +08:00
|
|
|
|
package logic
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"context"
|
|
|
|
|
|
"strconv"
|
2026-05-08 23:37:34 +08:00
|
|
|
|
"time"
|
2026-05-07 09:56:21 +08:00
|
|
|
|
|
|
|
|
|
|
"git.apinb.com/quant/coin/internal/impl"
|
|
|
|
|
|
"git.apinb.com/quant/coin/internal/models"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// loadPortfolio 从 GORM 读入全表 spot_positions,填充内存 map(键为 BaseAsset)。
|
|
|
|
|
|
func loadPortfolio() error {
|
|
|
|
|
|
portfolioMu.Lock()
|
|
|
|
|
|
defer portfolioMu.Unlock()
|
|
|
|
|
|
if impl.DBService == nil {
|
|
|
|
|
|
portfolio = models.NewSpotPortfolioSnapshot()
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
var rows []models.SpotPosition
|
|
|
|
|
|
if err := impl.DBService.Find(&rows).Error; err != nil {
|
|
|
|
|
|
return err
|
|
|
|
|
|
}
|
|
|
|
|
|
portfolio = models.NewSpotPortfolioSnapshot()
|
|
|
|
|
|
for i := range rows {
|
|
|
|
|
|
p := new(models.SpotPosition)
|
|
|
|
|
|
*p = rows[i]
|
|
|
|
|
|
portfolio.Positions[p.BaseAsset] = p
|
|
|
|
|
|
}
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-10 23:23:38 +08:00
|
|
|
|
func GetPortfolio() map[string]*models.SpotPosition {
|
|
|
|
|
|
portfolioMu.Lock()
|
|
|
|
|
|
defer portfolioMu.Unlock()
|
|
|
|
|
|
return portfolio.Positions
|
2026-05-08 23:37:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-10 23:23:38 +08:00
|
|
|
|
func RefreshAccount() error {
|
|
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
2026-05-08 23:37:34 +08:00
|
|
|
|
defer cancel()
|
2026-05-10 23:23:38 +08:00
|
|
|
|
acct, err := BinanceClient.NewGetAccountService().Do(ctx)
|
2026-05-08 23:37:34 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return err
|
|
|
|
|
|
}
|
2026-05-10 23:23:38 +08:00
|
|
|
|
accountMu.Lock()
|
|
|
|
|
|
defer accountMu.Unlock()
|
|
|
|
|
|
for _, b := range acct.Balances {
|
|
|
|
|
|
free, err := strconv.ParseFloat(b.Free, 64)
|
2026-05-08 23:37:34 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
2026-05-10 23:23:38 +08:00
|
|
|
|
account[b.Asset] = free
|
2026-05-08 23:37:34 +08:00
|
|
|
|
}
|
2026-05-10 23:23:38 +08:00
|
|
|
|
return nil
|
|
|
|
|
|
}
|
2026-05-08 23:37:34 +08:00
|
|
|
|
|
2026-05-10 23:23:38 +08:00
|
|
|
|
func GetAccount(asset string) float64 {
|
|
|
|
|
|
accountMu.Lock()
|
|
|
|
|
|
defer accountMu.Unlock()
|
|
|
|
|
|
free, ok := account[asset]
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
return 0
|
2026-05-08 23:37:34 +08:00
|
|
|
|
}
|
2026-05-10 23:23:38 +08:00
|
|
|
|
return free
|
2026-05-08 23:37:34 +08:00
|
|
|
|
}
|