67 lines
1.4 KiB
Go
67 lines
1.4 KiB
Go
package logic
|
||
|
||
import (
|
||
"context"
|
||
"strconv"
|
||
"time"
|
||
|
||
"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
|
||
}
|
||
|
||
func GetPortfolio() map[string]*models.SpotPosition {
|
||
portfolioMu.Lock()
|
||
defer portfolioMu.Unlock()
|
||
return portfolio.Positions
|
||
}
|
||
|
||
func RefreshAccount() error {
|
||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||
defer cancel()
|
||
acct, err := BinanceClient.NewGetAccountService().Do(ctx)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
accountMu.Lock()
|
||
defer accountMu.Unlock()
|
||
for _, b := range acct.Balances {
|
||
free, err := strconv.ParseFloat(b.Free, 64)
|
||
if err != nil {
|
||
continue
|
||
}
|
||
account[b.Asset] = free
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func GetAccount(asset string) float64 {
|
||
accountMu.Lock()
|
||
defer accountMu.Unlock()
|
||
free, ok := account[asset]
|
||
if !ok {
|
||
return 0
|
||
}
|
||
return free
|
||
}
|