github.com/diadata-org/diadata@v1.4.593/pkg/dia/pairs.go (about)

     1  package dia
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/diadata-org/diadata/pkg/utils"
     7  )
     8  
     9  // GetPairSymbols returns the two symbol tickers of @pair.
    10  func GetPairSymbols(pair ExchangePair) ([]string, error) {
    11  	if pair.Exchange == KrakenExchange {
    12  		pair = normalizeKrakenPair(pair)
    13  		foreignName := pair.ForeignName
    14  		quoteToken := pair.Symbol
    15  		baseToken := strings.TrimPrefix(foreignName, quoteToken)
    16  		return []string{quoteToken, baseToken}, nil
    17  	}
    18  	foreignName := pair.ForeignName
    19  	quoteToken := pair.Symbol
    20  
    21  	baseToken := strings.TrimPrefix(foreignName, quoteToken+"_")
    22  	if baseToken != foreignName {
    23  		return []string{quoteToken, baseToken}, nil
    24  	}
    25  	baseToken = strings.TrimPrefix(foreignName, quoteToken+"-")
    26  	if baseToken != foreignName {
    27  		return []string{quoteToken, baseToken}, nil
    28  	}
    29  	baseToken = strings.TrimPrefix(foreignName, quoteToken+"/")
    30  	if baseToken != foreignName {
    31  		return []string{quoteToken, baseToken}, nil
    32  	}
    33  	baseToken = strings.TrimPrefix(foreignName, quoteToken)
    34  	return []string{quoteToken, baseToken}, nil
    35  }
    36  
    37  // normalizeKrakenPair addresses the particular asset notation at Kraken.
    38  func normalizeKrakenPair(pair ExchangePair) ExchangePair {
    39  	if len(pair.ForeignName) == 7 {
    40  		if pair.ForeignName[len(pair.ForeignName)-3:] == "XBT" {
    41  			pair.ForeignName = pair.ForeignName[:len(pair.ForeignName)-3] + "BTC"
    42  		}
    43  		if pair.ForeignName[4:5] == "Z" || pair.ForeignName[4:5] == "X" {
    44  			pair.ForeignName = pair.ForeignName[:4] + pair.ForeignName[5:]
    45  		}
    46  		if pair.ForeignName[:1] == "Z" || pair.ForeignName[:1] == "X" {
    47  			pair.ForeignName = pair.ForeignName[1:]
    48  		}
    49  	}
    50  	if len(pair.ForeignName) == 8 {
    51  		if pair.ForeignName[4:5] == "Z" || pair.ForeignName[4:5] == "X" {
    52  			pair.ForeignName = pair.ForeignName[:4] + pair.ForeignName[5:]
    53  		}
    54  		if pair.ForeignName[:1] == "Z" || pair.ForeignName[:1] == "X" {
    55  			pair.ForeignName = pair.ForeignName[1:]
    56  		}
    57  	}
    58  	if pair.ForeignName[len(pair.ForeignName)-3:] == "XBT" {
    59  		pair.ForeignName = pair.ForeignName[:len(pair.ForeignName)-3] + "BTC"
    60  	}
    61  	if pair.ForeignName[:3] == "XBT" {
    62  		pair.ForeignName = "BTC" + pair.ForeignName[len(pair.ForeignName)-3:]
    63  	}
    64  	return pair
    65  }
    66  
    67  // GetAllSymbolsFromPairs returns a unique list of symbols which constitute @pairs.
    68  func GetAllSymbolsFromPairs(pairs []ExchangePair) ([]string, error) {
    69  	var symbols []string
    70  	for _, pair := range pairs {
    71  
    72  		pairsymbols, err := GetPairSymbols(pair)
    73  		if err != nil {
    74  			return []string{}, err
    75  		}
    76  		symbols = append(symbols, pairsymbols[0], pairsymbols[1])
    77  	}
    78  
    79  	uniqueSymbols := utils.UniqueStrings(symbols)
    80  	return uniqueSymbols, nil
    81  }
    82  
    83  // GetAllAssetsFromPairs returns the unique slice of assets underlying the exchange pairs @pairs.
    84  func GetAllAssetsFromPairs(pairs []ExchangePair) (assets []Asset) {
    85  	uniqueMap := make(map[Asset]struct{})
    86  
    87  	for _, pair := range pairs {
    88  		if _, ok := uniqueMap[pair.UnderlyingPair.BaseToken]; !ok {
    89  			assets = append(assets, pair.UnderlyingPair.BaseToken)
    90  			uniqueMap[pair.UnderlyingPair.BaseToken] = struct{}{}
    91  		}
    92  		if _, ok := uniqueMap[pair.UnderlyingPair.QuoteToken]; !ok {
    93  			assets = append(assets, pair.UnderlyingPair.QuoteToken)
    94  			uniqueMap[pair.UnderlyingPair.QuoteToken] = struct{}{}
    95  		}
    96  	}
    97  	return
    98  }
    99  
   100  // ContainsExchangePair returns true iff @pair is contained in pairs.
   101  // Here, equality refers to the unique identifier (exchange,foreignName).
   102  func ContainsExchangePair(pairs []ExchangePair, pair ExchangePair) bool {
   103  	for _, p := range pairs {
   104  		if pair.Exchange == p.Exchange && pair.ForeignName == p.ForeignName {
   105  			return true
   106  		}
   107  	}
   108  	return false
   109  }
   110  
   111  // MergeExchangePairs appends @pairs2 to @pairs1 without repetition.
   112  func MergeExchangePairs(pairs1, pairs2 []ExchangePair) []ExchangePair {
   113  	for _, pair := range pairs2 {
   114  		if ok := ContainsExchangePair(pairs1, pair); !ok {
   115  			pairs1 = append(pairs1, pair)
   116  		}
   117  	}
   118  	return pairs1
   119  }