package binance import ( "fmt" "time" "cryptoHermes/internal/entity" ) func parseKlineRow(symbol, interval string, row []any) (entity.Kline, error) { if len(row) < 12 { return entity.Kline{}, fmt.Errorf("binance kline row has %d fields, expected >=12", len(row)) } openTime, err := toInt64(row[0]) if err != nil { return entity.Kline{}, fmt.Errorf("openTime: %w", err) } closeTime, err := toInt64(row[6]) if err != nil { return entity.Kline{}, fmt.Errorf("closeTime: %w", err) } tradeCount, err := toInt64(row[8]) if err != nil { return entity.Kline{}, fmt.Errorf("tradeCount: %w", err) } open, _ := row[1].(string) high, _ := row[2].(string) low, _ := row[3].(string) closeP, _ := row[4].(string) volume, _ := row[5].(string) quoteVol, _ := row[7].(string) takerBase, _ := row[9].(string) takerQuote, _ := row[10].(string) nowMs := time.Now().UnixMilli() return entity.Kline{ Source: sourceName, Symbol: symbol, Interval: interval, OpenTime: openTime, CloseTime: closeTime, Open: open, High: high, Low: low, Close: closeP, Volume: volume, QuoteVolume: quoteVol, TradeCount: tradeCount, TakerBuyBaseVolume: takerBase, TakerBuyQuoteVolume: takerQuote, IsClosed: closeTime < nowMs, }, nil } func toInt64(v any) (int64, error) { switch x := v.(type) { case float64: return int64(x), nil case int64: return x, nil case int: return int64(x), nil default: return 0, fmt.Errorf("unexpected type %T", v) } } func mapTicker(d *tickerDTO) *entity.Ticker24h { return &entity.Ticker24h{ Symbol: d.Symbol, LastPrice: d.LastPrice, PriceChange: d.PriceChange, PriceChangePercent: d.PriceChangePercent, HighPrice: d.HighPrice, LowPrice: d.LowPrice, Volume: d.Volume, QuoteVolume: d.QuoteVolume, OpenTime: d.OpenTime, CloseTime: d.CloseTime, } } func mapPremiumIndex(d *premiumIndexDTO) *entity.FundingRate { return &entity.FundingRate{ Source: sourceName, Symbol: d.Symbol, FundingTime: d.NextFundingTime, FundingRate: d.LastFundingRate, MarkPrice: d.MarkPrice, } } func mapFundingHistory(d []fundingRateDTO) []entity.FundingRate { out := make([]entity.FundingRate, 0, len(d)) for _, x := range d { out = append(out, entity.FundingRate{ Source: sourceName, Symbol: x.Symbol, FundingTime: x.FundingTime, FundingRate: x.FundingRate, MarkPrice: x.MarkPrice, }) } return out } func mapOpenInterest(d *openInterestDTO, period string) *entity.OpenInterest { return &entity.OpenInterest{ Source: sourceName, Symbol: d.Symbol, Period: period, Timestamp: d.Time, OpenInterest: d.OpenInterest, } } func mapOpenInterestHistory(d []openInterestHistDTO, period string) []entity.OpenInterest { out := make([]entity.OpenInterest, 0, len(d)) for _, x := range d { out = append(out, entity.OpenInterest{ Source: sourceName, Symbol: x.Symbol, Period: period, Timestamp: x.Timestamp, OpenInterest: x.SumOpenInterest, OpenInterestValue: x.SumOpenInterestValue, }) } return out } func mapLongShort(d []longShortRatioDTO, period, ratioType string) []entity.LongShortRatio { out := make([]entity.LongShortRatio, 0, len(d)) for _, x := range d { longVal := x.LongAccount shortVal := x.ShortAccount if ratioType == entity.RatioTypeTopTraderPosition { longVal = x.LongPosition shortVal = x.ShortPosition } out = append(out, entity.LongShortRatio{ Source: sourceName, Symbol: x.Symbol, Period: period, RatioType: ratioType, Timestamp: x.Timestamp, LongShortRatio: x.LongShortRatio, LongValue: longVal, ShortValue: shortVal, }) } return out } func mapTakerVolume(d []takerVolumeDTO, symbol, period string) []entity.TakerBuySellVolume { out := make([]entity.TakerBuySellVolume, 0, len(d)) for _, x := range d { out = append(out, entity.TakerBuySellVolume{ Source: sourceName, Symbol: symbol, Period: period, Timestamp: x.Timestamp, BuySellRatio: x.BuySellRatio, BuyVolume: x.BuyVol, SellVolume: x.SellVol, }) } return out }