feat
This commit is contained in:
79
internal/logic/spot_binance_account.go
Normal file
79
internal/logic/spot_binance_account.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"git.apinb.com/quant/coin/internal/impl"
|
||||
"git.apinb.com/quant/coin/internal/models"
|
||||
"github.com/adshao/go-binance/v2"
|
||||
)
|
||||
|
||||
// refreshStepSizes 从 exchangeInfo 拉取各 symbol 的 LOT_SIZE.stepSize,供卖出数量格式化。
|
||||
func refreshStepSizes(ctx context.Context, client *binance.Client) error {
|
||||
watch := spotWatchesFromConfig()
|
||||
syms := make([]string, 0, len(watch))
|
||||
for _, w := range watch {
|
||||
syms = append(syms, w.Symbol)
|
||||
}
|
||||
info, err := client.NewExchangeInfoService().Symbols(syms...).Do(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, s := range info.Symbols {
|
||||
lot := s.LotSizeFilter()
|
||||
if lot == nil || lot.StepSize == "" {
|
||||
continue
|
||||
}
|
||||
stepSizes[s.Symbol] = lot.StepSize
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// savePortfolioLocked 将内存中各 SpotPosition 以 Save 写回数据库(有主键则更新,无则插入)。
|
||||
// 调用方必须已持有 portfolioMu。
|
||||
func savePortfolioLocked() error {
|
||||
if impl.DBService == nil {
|
||||
return nil
|
||||
}
|
||||
for _, st := range portfolio.Positions {
|
||||
if st == nil {
|
||||
continue
|
||||
}
|
||||
if err := impl.DBService.Save(st).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// balanceFree 从账户余额列表里解析某资产的可用数量(Free 字段为字符串)。
|
||||
func balanceFree(balances []binance.Balance, asset string) (float64, error) {
|
||||
for _, b := range balances {
|
||||
if b.Asset == asset {
|
||||
return strconv.ParseFloat(b.Free, 64)
|
||||
}
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
Reference in New Issue
Block a user