mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-06-06 05:51:19 +08:00
feat(hyperliquid): add stock symbol market data support
- Add Hyperliquid/XYZ symbol normalization tests and backend coverage - Extend kline and market data lookup paths for US stock symbols - Wire frontend data API types for stock-oriented market requests
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"io"
|
||||
"math"
|
||||
"nofx/logger"
|
||||
"nofx/provider/hyperliquid"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -229,7 +230,7 @@ func GetWithTimeframes(symbol string, timeframes []string, primaryTimeframe stri
|
||||
currentRSI7 := calculateRSI(primaryKlines, 7)
|
||||
|
||||
// Calculate price changes
|
||||
priceChange1h := calculatePriceChangeByBars(primaryKlines, primaryTimeframe, 60) // 1 hour
|
||||
priceChange1h := calculatePriceChangeByBars(primaryKlines, primaryTimeframe, 60) // 1 hour
|
||||
priceChange4h := calculatePriceChangeByBars(primaryKlines, primaryTimeframe, 240) // 4 hours
|
||||
|
||||
// Get OI data
|
||||
@@ -540,6 +541,9 @@ var xyzDexAssets = map[string]bool{
|
||||
// IsXyzDexAsset checks if a symbol is an xyz dex asset
|
||||
func IsXyzDexAsset(symbol string) bool {
|
||||
base := strings.ToUpper(symbol)
|
||||
if strings.HasSuffix(base, "-USDC") || strings.HasPrefix(strings.ToLower(base), "xyz:") {
|
||||
return hyperliquid.IsXYZAsset(base)
|
||||
}
|
||||
// Remove any prefix/suffix
|
||||
base = strings.TrimPrefix(base, "XYZ:")
|
||||
for _, suffix := range []string{"USDT", "USD", "-USDC"} {
|
||||
@@ -548,7 +552,7 @@ func IsXyzDexAsset(symbol string) bool {
|
||||
break
|
||||
}
|
||||
}
|
||||
return xyzDexAssets[base]
|
||||
return xyzDexAssets[base] || hyperliquid.IsXYZAsset(base)
|
||||
}
|
||||
|
||||
// Normalize normalizes symbol
|
||||
@@ -556,22 +560,13 @@ func IsXyzDexAsset(symbol string) bool {
|
||||
// For xyz dex assets (stocks, forex, commodities): uses xyz: prefix without USDT suffix
|
||||
func Normalize(symbol string) string {
|
||||
symbol = strings.ToUpper(symbol)
|
||||
if strings.HasSuffix(symbol, "-USDC") {
|
||||
return hyperliquid.FormatCoinForAPI(symbol)
|
||||
}
|
||||
|
||||
// Check if this is an xyz dex asset
|
||||
if IsXyzDexAsset(symbol) {
|
||||
// Remove any xyz: prefix (case-insensitive) and USDT suffix, then add xyz: prefix
|
||||
base := symbol
|
||||
// Handle both lowercase and uppercase xyz: prefix
|
||||
if strings.HasPrefix(strings.ToLower(base), "xyz:") {
|
||||
base = base[4:] // Remove first 4 characters ("xyz:")
|
||||
}
|
||||
for _, suffix := range []string{"USDT", "USD", "-USDC"} {
|
||||
if strings.HasSuffix(base, suffix) {
|
||||
base = strings.TrimSuffix(base, suffix)
|
||||
break
|
||||
}
|
||||
}
|
||||
return "xyz:" + base
|
||||
return hyperliquid.FormatCoinForAPI(symbol)
|
||||
}
|
||||
|
||||
// Remove exchange-specific separators (Gate uses BTC_USDT, OKX uses BTC-USDT-SWAP)
|
||||
|
||||
26
market/data_hyperliquid_xyz_test.go
Normal file
26
market/data_hyperliquid_xyz_test.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package market
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestHyperliquidXYZAliasesNormalizeForAIDecisionData(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
normalized string
|
||||
isXyzAsset bool
|
||||
}{
|
||||
{input: "SMSN-USDC", normalized: "xyz:SMSN", isXyzAsset: true},
|
||||
{input: "SAMSUNG-USDC", normalized: "xyz:SMSN", isXyzAsset: true},
|
||||
{input: "xyz:SMSN", normalized: "xyz:SMSN", isXyzAsset: true},
|
||||
{input: "TESLA-USDC", normalized: "xyz:TSLA", isXyzAsset: true},
|
||||
{input: "TSLA-USDC", normalized: "xyz:TSLA", isXyzAsset: true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
if got := Normalize(tt.input); got != tt.normalized {
|
||||
t.Fatalf("Normalize(%q) = %q, want %q", tt.input, got, tt.normalized)
|
||||
}
|
||||
if got := IsXyzDexAsset(tt.normalized); got != tt.isXyzAsset {
|
||||
t.Fatalf("IsXyzDexAsset(%q) = %v, want %v", tt.normalized, got, tt.isXyzAsset)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user