package market import ( "context" "strings" "time" "github.com/rs/zerolog/log" ) func (ms *MarketData) refreshFuturePairCache() error { ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() futuresInfo, err := ms.futuresClient.NewExchangeInfoService().Do(ctx) if err != nil { log.Error().Err(err).Msg("Failed to fetch futures exchange info") return err } futurePairs := make(map[string]bool, len(futuresInfo.Symbols)) futureTokenCandidates := make(map[string][]string) for _, s := range futuresInfo.Symbols { if s.Status != "TRADING" { continue } futurePairs[s.Symbol] = true token := parseTokenFromSymbolByQuotePriority(s.Symbol) if token == "" { continue } token = futureCacheTokenKey(token) futureTokenCandidates[token] = append(futureTokenCandidates[token], s.Symbol) } futureToken2Symbol := make(map[string]string, len(futureTokenCandidates)) for token, candidates := range futureTokenCandidates { futureToken2Symbol[token] = selectCanonicalSymbolByQuotePriority(token, candidates) } ms.pairCacheMutex.Lock() ms.futuresPairs = futurePairs ms.futureToken2Symbol = futureToken2Symbol ms.lastPairCacheUpdate = time.Now() ms.pairCacheMutex.Unlock() return nil } func futureCacheTokenKey(token string) string { return strings.ToUpper(token) } func (ms *MarketData) IsFuturesPair(symbol string) bool { ms.pairCacheMutex.RLock() defer ms.pairCacheMutex.RUnlock() return ms.futuresPairs[symbol] } func (ms *MarketData) GetFutureSymbolByToken(token string) (string, bool) { ms.pairCacheMutex.RLock() defer ms.pairCacheMutex.RUnlock() sym, ok := ms.futureToken2Symbol[strings.ToUpper(token)] return sym, ok }