fix: resolve spot and futures symbols via shared resolver
Introduce a shared token symbol resolver for spot and futures lookups while keeping alpha lookup independent, restoring prefix/remap handling and preserving spot-only fallback behavior. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"gopkg.in/telebot.v3"
|
||||
"me.thuanle/bbot/internal/configs/tele"
|
||||
"me.thuanle/bbot/internal/data"
|
||||
"me.thuanle/bbot/internal/helper/binancex"
|
||||
"me.thuanle/bbot/internal/services/tele/chat"
|
||||
"me.thuanle/bbot/internal/services/tele/view"
|
||||
)
|
||||
@@ -75,21 +76,23 @@ func collectRichTokenData(token string) buildRichTokenMessageArgs {
|
||||
}
|
||||
}
|
||||
|
||||
futureSymbol := token + "USDT"
|
||||
if data.Market.IsFuturesPair(futureSymbol) {
|
||||
futureSymbols := binancex.Token2FutureSymbols(token)
|
||||
for _, futureSymbol := range futureSymbols {
|
||||
if fp, fr, ft, ok := data.Market.GetFuturePrice(futureSymbol); ok {
|
||||
a.HasFuture = true
|
||||
a.FuturePrice = fp
|
||||
a.FundingRate = fr
|
||||
a.FundingTimeMs = ft
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
spotSymbol := token + "USDT"
|
||||
if data.Market.IsSpotPair(spotSymbol) {
|
||||
spotSymbols := binancex.Token2SpotSymbols(token)
|
||||
for _, spotSymbol := range spotSymbols {
|
||||
if sp, ok := data.Market.GetSpotPrice(spotSymbol); ok {
|
||||
a.HasSpot = true
|
||||
a.SpotPrice = sp
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -113,9 +113,15 @@ func TestCollectRichTokenData_FutureFailureStillKeepsSpot(t *testing.T) {
|
||||
defer func() { data.Market = orig }()
|
||||
|
||||
data.Market = &marketStub{
|
||||
spotPairs: map[string]bool{"ETHUSDT": true},
|
||||
futuresPairs: map[string]bool{"ETHUSDT": true},
|
||||
spotPrices: map[string]float64{"ETHUSDT": 3245},
|
||||
spotPairs: map[string]bool{
|
||||
"ETHUSDT": true,
|
||||
},
|
||||
futuresPairs: map[string]bool{
|
||||
"ETHUSDT": true,
|
||||
},
|
||||
spotPrices: map[string]float64{
|
||||
"ETHUSDT": 3245,
|
||||
},
|
||||
futurePrices: map[string]struct {
|
||||
price float64
|
||||
rate float64
|
||||
@@ -132,6 +138,67 @@ func TestCollectRichTokenData_FutureFailureStillKeepsSpot(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectRichTokenData_UsesSharedResolverMapping(t *testing.T) {
|
||||
orig := data.Market
|
||||
defer func() { data.Market = orig }()
|
||||
|
||||
data.Market = &marketStub{
|
||||
spotPairs: map[string]bool{
|
||||
"LUNAUSDT": true,
|
||||
},
|
||||
futuresPairs: map[string]bool{
|
||||
"LUNA2USDT": true,
|
||||
},
|
||||
spotPrices: map[string]float64{
|
||||
"LUNAUSDT": 0.49,
|
||||
},
|
||||
futurePrices: map[string]struct {
|
||||
price float64
|
||||
rate float64
|
||||
time int64
|
||||
}{
|
||||
"LUNA2USDT": {price: 0.50, rate: 0.0001, time: 1740000000000},
|
||||
},
|
||||
}
|
||||
|
||||
args := collectRichTokenData("LUNA2")
|
||||
if !args.HasFuture || !args.HasSpot {
|
||||
t.Fatalf("expected both future and mapped spot, got %+v", args)
|
||||
}
|
||||
if args.SpotPrice != 0.49 {
|
||||
t.Fatalf("expected mapped spot price 0.49, got %f", args.SpotPrice)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectRichTokenData_PrefixFutureMapsToSpot(t *testing.T) {
|
||||
orig := data.Market
|
||||
defer func() { data.Market = orig }()
|
||||
|
||||
data.Market = &marketStub{
|
||||
spotPairs: map[string]bool{
|
||||
"PEPEUSDT": true,
|
||||
},
|
||||
futuresPairs: map[string]bool{
|
||||
"1000PEPEUSDT": true,
|
||||
},
|
||||
spotPrices: map[string]float64{
|
||||
"PEPEUSDT": 0.000012,
|
||||
},
|
||||
futurePrices: map[string]struct {
|
||||
price float64
|
||||
rate float64
|
||||
time int64
|
||||
}{
|
||||
"1000PEPEUSDT": {price: 0.000013, rate: 0.0002, time: 1740000000000},
|
||||
},
|
||||
}
|
||||
|
||||
args := collectRichTokenData("PEPE")
|
||||
if !args.HasFuture || !args.HasSpot {
|
||||
t.Fatalf("expected both future and mapped spot for prefixed contract, got %+v", args)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectRichTokenData_AlphaUsesSymbolPrice(t *testing.T) {
|
||||
orig := data.Market
|
||||
defer func() { data.Market = orig }()
|
||||
|
||||
Reference in New Issue
Block a user