mirror of
https://github.com/luxfi/dex.git
synced 2026-09-24 00:26:31 +00:00
153 lines
3.6 KiB
Go
153 lines
3.6 KiB
Go
package price
|
|
|
|
import "strings"
|
|
|
|
// Normalize standardizes a trading symbol across different sources.
|
|
// Handles variations like:
|
|
// - LUX/USDC, LUX-USDC, LUXUSDC -> LUX-USDC
|
|
// - ETH/USD, ETH-USD, ETHUSD -> ETH-USD
|
|
// - BTC/USDT, BTC-USDT, BTCUSDT -> BTC-USDT
|
|
func Normalize(symbol string) string {
|
|
s := strings.ToUpper(symbol)
|
|
s = strings.ReplaceAll(s, "/", "-")
|
|
s = strings.ReplaceAll(s, "_", "-")
|
|
s = strings.TrimSpace(s)
|
|
|
|
// If no separator, try to detect pair
|
|
if !strings.Contains(s, "-") {
|
|
s = detectPair(s)
|
|
}
|
|
|
|
return s
|
|
}
|
|
|
|
func detectPair(s string) string {
|
|
// Common quote currencies to detect
|
|
quotes := []string{"USDC", "USDT", "USD", "BTC", "ETH", "LUX"}
|
|
|
|
for _, q := range quotes {
|
|
if strings.HasSuffix(s, q) && len(s) > len(q) {
|
|
base := s[:len(s)-len(q)]
|
|
return base + "-" + q
|
|
}
|
|
}
|
|
return s
|
|
}
|
|
|
|
// SymbolMap maps source-specific symbols to normalized form.
|
|
type SymbolMap struct {
|
|
aliases map[string]string
|
|
}
|
|
|
|
// NewSymbolMap creates a symbol mapper with default aliases.
|
|
func NewSymbolMap() *SymbolMap {
|
|
return &SymbolMap{
|
|
aliases: defaultAliases(),
|
|
}
|
|
}
|
|
|
|
func defaultAliases() map[string]string {
|
|
return map[string]string{
|
|
// USD variations -> keep as USD (oracle standard)
|
|
"LUX/USD": "LUX-USD",
|
|
"LUXUSD": "LUX-USD",
|
|
"ETH/USD": "ETH-USD",
|
|
"ETHUSD": "ETH-USD",
|
|
"BTC/USD": "BTC-USD",
|
|
"BTCUSD": "BTC-USD",
|
|
"AVAX/USD": "AVAX-USD",
|
|
"AVAXUSD": "AVAX-USD",
|
|
"SOL/USD": "SOL-USD",
|
|
"SOLUSD": "SOL-USD",
|
|
|
|
// USDC variations
|
|
"LUX/USDC": "LUX-USDC",
|
|
"LUXUSDC": "LUX-USDC",
|
|
"ETH/USDC": "ETH-USDC",
|
|
"ETHUSDC": "ETH-USDC",
|
|
"BTC/USDC": "BTC-USDC",
|
|
"BTCUSDC": "BTC-USDC",
|
|
"AVAX/USDC": "AVAX-USDC",
|
|
"AVAXUSDC": "AVAX-USDC",
|
|
|
|
// USDT variations
|
|
"LUX-USDT": "LUX-USDT",
|
|
"LUX/USDT": "LUX-USDT",
|
|
"LUXUSDT": "LUX-USDT",
|
|
"ETH-USDT": "ETH-USDT",
|
|
"ETH/USDT": "ETH-USDT",
|
|
"ETHUSDT": "ETH-USDT",
|
|
"BTC-USDT": "BTC-USDT",
|
|
"BTC/USDT": "BTC-USDT",
|
|
"BTCUSDT": "BTC-USDT",
|
|
"AVAX-USDT": "AVAX-USDT",
|
|
"AVAX/USDT": "AVAX-USDT",
|
|
"AVAXUSDT": "AVAX-USDT",
|
|
}
|
|
}
|
|
|
|
// Map converts a symbol to its normalized form.
|
|
func (m *SymbolMap) Map(symbol string) string {
|
|
s := Normalize(symbol)
|
|
if alias, ok := m.aliases[s]; ok {
|
|
return alias
|
|
}
|
|
return s
|
|
}
|
|
|
|
// AddAlias adds a symbol alias.
|
|
func (m *SymbolMap) AddAlias(from, to string) {
|
|
m.aliases[Normalize(from)] = Normalize(to)
|
|
}
|
|
|
|
// Reverse finds source symbols that map to a normalized symbol.
|
|
func (m *SymbolMap) Reverse(normalized string) []string {
|
|
result := []string{normalized}
|
|
target := Normalize(normalized)
|
|
|
|
for from, to := range m.aliases {
|
|
if Normalize(to) == target {
|
|
result = append(result, from)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
// BaseQuote splits a symbol into base and quote currencies.
|
|
func BaseQuote(symbol string) (base, quote string) {
|
|
s := Normalize(symbol)
|
|
parts := strings.Split(s, "-")
|
|
if len(parts) == 2 {
|
|
return parts[0], parts[1]
|
|
}
|
|
return s, ""
|
|
}
|
|
|
|
// Quote extracts the quote currency from a symbol.
|
|
func Quote(symbol string) string {
|
|
_, q := BaseQuote(symbol)
|
|
return q
|
|
}
|
|
|
|
// Base extracts the base currency from a symbol.
|
|
func Base(symbol string) string {
|
|
b, _ := BaseQuote(symbol)
|
|
return b
|
|
}
|
|
|
|
// SameBase returns true if two symbols have the same base currency.
|
|
func SameBase(a, b string) bool {
|
|
return Base(a) == Base(b)
|
|
}
|
|
|
|
// SameQuote returns true if two symbols have the same quote currency.
|
|
func SameQuote(a, b string) bool {
|
|
return Quote(a) == Quote(b)
|
|
}
|
|
|
|
// IsUSD returns true if the symbol is quoted in a USD stablecoin.
|
|
func IsUSD(symbol string) bool {
|
|
q := Quote(symbol)
|
|
return q == "USD" || q == "USDC" || q == "USDT" || q == "BUSD" || q == "DAI"
|
|
}
|