codebase: Cleanup various things (#1935)

* codebase: Rid base64/hex to string common funcs

* codebase: Rid local scope variable usage and other improvements

* codebase: Refactor currency pair usage across multiple exchanges

- Updated HitBTC tests to use the new currency pair format.
- Modified Kraken futures types to use currency.Pair instead of string for Symbol.
- Adjusted Kraken wrapper methods to handle currency pairs correctly.
- Refined OKX tests and types to utilize currency.Pair for instrument IDs.
- Enhanced Poloniex tests to consistently use predefined currency pairs.
- Streamlined order and orderbook tests to replace string pairs with currency.NewBTCUSD().
- Improved Yobit tests to utilize a standardized currency pair format.
- Updated validator wrapper to use currency pairs directly instead of string conversions.

* codebase: Use types.Number where possible

* refactor: update PayoutFee type to types.Number for consistency

* Refactor: Remove crypto functions to use standard library and other minor changes

- Removed custom crypto functions for SHA256, SHA512, and MD5 from the common/crypto package.
- Replaced usages of removed functions with standard library implementations in various files including:
  - cmd/websocket_client/main.go
  - engine/apiserver.go
  - exchanges/kraken/kraken.go
  - exchanges/lbank/lbank.go
  - exchanges/okx/okx_business_websocket.go
  - exchanges/kucoin/kucoin_websocket.go
  - gctscript/vm/vm.go
- Updated tests to reflect changes in the crypto functions.
- Renamed several functions for clarity, particularly in the context of order book updates across multiple exchanges.

* refactor: replace assert with require for consistency in test assertions

* refactor: Improve Binance futures candlestick test, standardise orderbook update function names and improve test parallelism

* refactor: Replace require.Len with require.Equal for better output in TestGetFuturesKlineData
This commit is contained in:
Adrian Gallagher
2025-06-12 14:12:36 +10:00
committed by GitHub
parent ce134a0a1d
commit d5ba674fc4
115 changed files with 1327 additions and 3112 deletions

View File

@@ -2,6 +2,7 @@ package binanceus
import (
"context"
"encoding/hex"
"errors"
"fmt"
"net/http"
@@ -335,47 +336,26 @@ func (bi *Binanceus) GetOrderBookDepth(ctx context.Context, arg *OrderBookDataRe
}
params.Set("symbol", symbol)
params.Set("limit", strconv.FormatInt(arg.Limit, 10))
var resp OrderBookData
if err := bi.SendHTTPRequest(ctx,
exchange.RestSpotSupplementary,
common.EncodeURLValues(orderBookDepth, params),
orderbookLimit(arg.Limit), &resp); err != nil {
var resp *OrderBookData
if err := bi.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, common.EncodeURLValues(orderBookDepth, params), orderbookLimit(arg.Limit), &resp); err != nil {
return nil, err
}
orderbook := OrderBook{
ob := &OrderBook{
Bids: make([]OrderbookItem, len(resp.Bids)),
Asks: make([]OrderbookItem, len(resp.Asks)),
LastUpdateID: resp.LastUpdateID,
}
for x := range resp.Bids {
price, err := strconv.ParseFloat(resp.Bids[x][0], 64)
if err != nil {
return nil, err
}
amount, err := strconv.ParseFloat(resp.Bids[x][1], 64)
if err != nil {
return nil, err
}
orderbook.Bids[x] = OrderbookItem{
Price: price,
Quantity: amount,
}
ob.Bids[x].Price = resp.Bids[x][0].Float64()
ob.Bids[x].Quantity = resp.Bids[x][1].Float64()
}
for x := range resp.Asks {
price, err := strconv.ParseFloat(resp.Asks[x][0], 64)
if err != nil {
return nil, err
}
amount, err := strconv.ParseFloat(resp.Asks[x][1], 64)
if err != nil {
return nil, err
}
orderbook.Asks[x] = OrderbookItem{
Price: price,
Quantity: amount,
}
ob.Asks[x].Price = resp.Asks[x][0].Float64()
ob.Asks[x].Quantity = resp.Asks[x][1].Float64()
}
return &orderbook, nil
return ob, nil
}
// GetIntervalEnum allowed interval params by Binanceus
@@ -1804,21 +1784,14 @@ func (bi *Binanceus) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL
}
interim := json.RawMessage{}
err = bi.SendPayload(ctx, f, func() (*request.Item, error) {
fullPath := endpointPath + path
params.Set("timestamp", strconv.FormatInt(time.Now().UnixMilli(), 10))
signature := params.Encode()
var hmacSigned []byte
hmacSigned, err = crypto.GetHMAC(crypto.HashSHA256,
[]byte(signature),
[]byte(creds.Secret))
hmacSigned, err := crypto.GetHMAC(crypto.HashSHA256, []byte(params.Encode()), []byte(creds.Secret))
if err != nil {
return nil, err
}
hmacSignedStr := crypto.HexEncodeToString(hmacSigned)
headers := make(map[string]string)
headers["X-MBX-APIKEY"] = creds.Key
fullPath = common.EncodeURLValues(fullPath, params)
fullPath += "&signature=" + hmacSignedStr
fullPath := common.EncodeURLValues(endpointPath+path, params) + "&signature=" + hex.EncodeToString(hmacSigned)
return &request.Item{
Method: method,
Path: fullPath,

View File

@@ -174,9 +174,9 @@ type OrderbookItem struct {
// OrderBookData is resp data from orderbook endpoint
type OrderBookData struct {
LastUpdateID int64 `json:"lastUpdateId"`
Bids [][2]string `json:"bids"`
Asks [][2]string `json:"asks"`
LastUpdateID int64 `json:"lastUpdateId"`
Bids [][2]types.Number `json:"bids"`
Asks [][2]types.Number `json:"asks"`
}
// OrderBook actual structured data that can be used for orderbook
@@ -827,20 +827,20 @@ type update struct {
// WebsocketDepthStream is the difference for the update depth stream
type WebsocketDepthStream struct {
Event string `json:"e"`
Timestamp types.Time `json:"E"`
Pair string `json:"s"`
FirstUpdateID int64 `json:"U"`
LastUpdateID int64 `json:"u"`
UpdateBids [][2]string `json:"b"`
UpdateAsks [][2]string `json:"a"`
Event string `json:"e"`
Timestamp types.Time `json:"E"`
Pair string `json:"s"`
FirstUpdateID int64 `json:"U"`
LastUpdateID int64 `json:"u"`
UpdateBids [][2]types.Number `json:"b"`
UpdateAsks [][2]types.Number `json:"a"`
}
// WebsocketDepthDiffStream websocket response of depth diff stream
type WebsocketDepthDiffStream struct {
LastUpdateID int64 `json:"lastUpdateId"`
Bids [][2]string `json:"bids"`
Asks [][2]string `json:"asks"`
LastUpdateID int64 `json:"lastUpdateId"`
Bids [][2]types.Number `json:"bids"`
Asks [][2]types.Number `json:"asks"`
}
// WsAccountInfoData defines websocket account info data
@@ -963,17 +963,17 @@ type WsListStatusData struct {
// TradeStream holds the trade stream data
type TradeStream struct {
EventType string `json:"e"`
EventTime types.Time `json:"E"`
Symbol string `json:"s"`
TradeID int64 `json:"t"`
Price string `json:"p"`
Quantity string `json:"q"`
BuyerOrderID int64 `json:"b"`
SellerOrderID int64 `json:"a"`
TimeStamp types.Time `json:"T"`
Maker bool `json:"m"`
BestMatchPrice bool `json:"M"`
EventType string `json:"e"`
EventTime types.Time `json:"E"`
Symbol string `json:"s"`
TradeID int64 `json:"t"`
Price types.Number `json:"p"`
Quantity types.Number `json:"q"`
BuyerOrderID int64 `json:"b"`
SellerOrderID int64 `json:"a"`
TimeStamp types.Time `json:"T"`
Maker bool `json:"m"`
BestMatchPrice bool `json:"M"`
}
// KlineStream holds the kline stream data

View File

@@ -314,11 +314,10 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error {
switch streamType[1] {
case "trade":
saveTradeData := bi.IsSaveTradeDataEnabled()
if !saveTradeData &&
!bi.IsTradeFeedEnabled() {
if !saveTradeData && !bi.IsTradeFeedEnabled() {
return nil
}
var t TradeStream
err = json.Unmarshal(rawData, &t)
if err != nil {
@@ -327,19 +326,6 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error {
err)
}
price, err := strconv.ParseFloat(t.Price, 64)
if err != nil {
return fmt.Errorf("%v - price conversion error: %s",
bi.Name,
err)
}
amount, err := strconv.ParseFloat(t.Quantity, 64)
if err != nil {
return fmt.Errorf("%v - amount conversion error: %s",
bi.Name,
err)
}
pair, err := currency.NewPairFromFormattedPairs(t.Symbol, pairs, format)
if err != nil {
return err
@@ -349,8 +335,8 @@ func (bi *Binanceus) wsHandleData(respRaw []byte) error {
trade.Data{
CurrencyPair: pair,
Timestamp: t.TimeStamp.Time(),
Price: price,
Amount: amount,
Price: t.Price.Float64(),
Amount: t.Quantity.Float64(),
Exchange: bi.Name,
AssetType: asset.Spot,
TID: strconv.FormatInt(t.TradeID, 10),
@@ -668,44 +654,26 @@ func (bi *Binanceus) SynchroniseWebsocketOrderbook() {
}()
}
// ProcessUpdate processes the websocket orderbook update
func (bi *Binanceus) ProcessUpdate(cp currency.Pair, a asset.Item, ws *WebsocketDepthStream) error {
updateBid := make([]orderbook.Tranche, len(ws.UpdateBids))
for i := range ws.UpdateBids {
price := ws.UpdateBids[i][0]
p, err := strconv.ParseFloat(price, 64)
if err != nil {
return err
}
amount := ws.UpdateBids[i][1]
a, err := strconv.ParseFloat(amount, 64)
if err != nil {
return err
}
updateBid[i] = orderbook.Tranche{Price: p, Amount: a}
// ProcessOrderbookUpdate processes the websocket orderbook update
func (bi *Binanceus) ProcessOrderbookUpdate(cp currency.Pair, a asset.Item, wsDSUpdate *WebsocketDepthStream) error {
updateBid := make([]orderbook.Tranche, len(wsDSUpdate.UpdateBids))
for i := range wsDSUpdate.UpdateBids {
updateBid[i].Price = wsDSUpdate.UpdateBids[i][0].Float64()
updateBid[i].Amount = wsDSUpdate.UpdateBids[i][1].Float64()
}
updateAsk := make([]orderbook.Tranche, len(ws.UpdateAsks))
for i := range ws.UpdateAsks {
price := ws.UpdateAsks[i][0]
p, err := strconv.ParseFloat(price, 64)
if err != nil {
return err
}
amount := ws.UpdateAsks[i][1]
a, err := strconv.ParseFloat(amount, 64)
if err != nil {
return err
}
updateAsk[i] = orderbook.Tranche{Price: p, Amount: a}
updateAsk := make([]orderbook.Tranche, len(wsDSUpdate.UpdateAsks))
for i := range wsDSUpdate.UpdateAsks {
updateAsk[i].Price = wsDSUpdate.UpdateAsks[i][0].Float64()
updateAsk[i].Amount = wsDSUpdate.UpdateAsks[i][1].Float64()
}
return bi.Websocket.Orderbook.Update(&orderbook.Update{
Bids: updateBid,
Asks: updateAsk,
Pair: cp,
UpdateID: ws.LastUpdateID,
UpdateTime: ws.Timestamp.Time(),
UpdateID: wsDSUpdate.LastUpdateID,
UpdateTime: wsDSUpdate.Timestamp.Time(),
Asset: a,
})
}
@@ -762,7 +730,7 @@ func (bi *Binanceus) applyBufferUpdate(pair currency.Pair) error {
}
if recent != nil {
err = bi.obm.checkAndProcessUpdate(bi.ProcessUpdate, pair, recent)
err = bi.obm.checkAndProcessOrderbookUpdate(bi.ProcessOrderbookUpdate, pair, recent)
if err != nil {
log.Errorf(
log.WebsocketMgr,
@@ -1017,7 +985,7 @@ func (o *orderbookManager) stopNeedsFetchingBook(pair currency.Pair) error {
return nil
}
func (o *orderbookManager) checkAndProcessUpdate(processor func(currency.Pair, asset.Item, *WebsocketDepthStream) error, pair currency.Pair, recent *orderbook.Base) error {
func (o *orderbookManager) checkAndProcessOrderbookUpdate(processor func(currency.Pair, asset.Item, *WebsocketDepthStream) error, pair currency.Pair, recent *orderbook.Base) error {
o.Lock()
defer o.Unlock()
state, ok := o.state[pair.Base][pair.Quote][asset.Spot]