Rewrite price lookup from WebSocket to REST API

Replace unreliable WebSocket connections with on-demand REST API calls
for spot and futures prices. Add cached trading pair list (refreshed
hourly) for symbol validation, and /refresh command for manual updates.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-26 15:14:09 +07:00
parent c5c1cdf0d5
commit 9c39423315
8 changed files with 169 additions and 93 deletions
+22 -34
View File
@@ -1,21 +1,36 @@
package market
import (
"context"
"strconv"
"time"
"github.com/adshao/go-binance/v2"
"github.com/rs/zerolog/log"
)
func (ms *MarketData) GetSpotPrice(symbol string) (float64, bool) {
ms.mu.RLock()
p, ok := ms.spotPrice[symbol]
ms.mu.RUnlock()
if ok {
return p, true
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
prices, err := ms.spotClient.NewListPricesService().Symbol(symbol).Do(ctx)
if err != nil {
log.Error().Err(err).Str("symbol", symbol).Msg("Failed to fetch spot price")
return ms.getAlphaPrice(symbol)
}
// If not found, check if it's an Alpha token
if len(prices) == 0 {
return ms.getAlphaPrice(symbol)
}
price, err := strconv.ParseFloat(prices[0].Price, 64)
if err != nil || price == 0 {
return ms.getAlphaPrice(symbol)
}
return price, true
}
func (ms *MarketData) getAlphaPrice(symbol string) (float64, bool) {
if ms.IsAlphaToken(symbol) {
if alphaToken, exists := ms.GetAlphaToken(symbol); exists {
if price := alphaToken.GetPrice(); price > 0 {
@@ -23,32 +38,5 @@ func (ms *MarketData) GetSpotPrice(symbol string) (float64, bool) {
}
}
}
return 0, false
}
func (ms *MarketData) StartSpotWsMarkPrice() error {
_, _, err := binance.WsAllMarketsStatServe(ms.spotWsAllMarketsStatHandler, ms.spotWsErrHandler) //.WsAllMarkPriceServe(ms.futureWsMarkPriceHandler, ms.futureWsErrHandler)
if err != nil {
return err
}
return nil
}
func (ms *MarketData) spotWsAllMarketsStatHandler(event binance.WsAllMarketsStatEvent) {
ms.mu.Lock()
defer ms.mu.Unlock()
for _, priceEvent := range event {
price, err := strconv.ParseFloat(priceEvent.LastPrice, 64)
if err != nil {
continue
}
ms.spotPrice[priceEvent.Symbol] = price
}
}
func (ms *MarketData) spotWsErrHandler(err error) {
log.Debug().Err(err).Msg("Spot Ws Error. Restart socket")
_ = ms.StartSpotWsMarkPrice()
}