Skip to content

Commit

Permalink
Merge pull request #1492 from c9s/edwin/okx/refactor-tickers
Browse files Browse the repository at this point in the history
FEATURE: [okx] generate ticker request by requestgen
  • Loading branch information
bailantaotao authored Jan 9, 2024
2 parents 0bf1e4e + 188b781 commit c2e3fed
Show file tree
Hide file tree
Showing 7 changed files with 463 additions and 90 deletions.
23 changes: 18 additions & 5 deletions pkg/exchange/okex/exchange.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ var (
marketDataLimiter = rate.NewLimiter(rate.Every(100*time.Millisecond), 5)
orderRateLimiter = rate.NewLimiter(rate.Every(300*time.Millisecond), 5)

queryMarketLimiter = rate.NewLimiter(rate.Every(100*time.Millisecond), 10)
queryMarketLimiter = rate.NewLimiter(rate.Every(100*time.Millisecond), 10)
queryTickerLimiter = rate.NewLimiter(rate.Every(100*time.Millisecond), 10)
queryTickersLimiter = rate.NewLimiter(rate.Every(100*time.Millisecond), 10)
)

const ID = "okex"
Expand Down Expand Up @@ -112,18 +114,29 @@ func (e *Exchange) QueryMarkets(ctx context.Context) (types.MarketMap, error) {
}

func (e *Exchange) QueryTicker(ctx context.Context, symbol string) (*types.Ticker, error) {
symbol = toLocalSymbol(symbol)
if err := queryTickerLimiter.Wait(ctx); err != nil {
return nil, fmt.Errorf("ticker rate limiter wait error: %w", err)
}

marketTicker, err := e.client.MarketTicker(ctx, symbol)
symbol = toLocalSymbol(symbol)
marketTicker, err := e.client.NewGetTickerRequest().InstId(symbol).Do(ctx)
if err != nil {
return nil, err
}

return toGlobalTicker(*marketTicker), nil
if len(marketTicker) != 1 {
return nil, fmt.Errorf("unexpected length of %s market ticker, got: %v", symbol, marketTicker)
}

return toGlobalTicker(marketTicker[0]), nil
}

func (e *Exchange) QueryTickers(ctx context.Context, symbols ...string) (map[string]types.Ticker, error) {
marketTickers, err := e.client.MarketTickers(ctx, okexapi.InstrumentTypeSpot)
if err := queryTickersLimiter.Wait(ctx); err != nil {
return nil, fmt.Errorf("tickers rate limiter wait error: %w", err)
}

marketTickers, err := e.client.NewGetTickersRequest().Do(ctx)
if err != nil {
return nil, err
}
Expand Down
85 changes: 0 additions & 85 deletions pkg/exchange/okex/okexapi/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"net/url"
"strings"
Expand Down Expand Up @@ -273,90 +272,6 @@ func (c *RestClient) AssetCurrencies(ctx context.Context) ([]AssetCurrency, erro
return currencyResponse.Data, nil
}

type MarketTicker struct {
InstrumentType string `json:"instType"`
InstrumentID string `json:"instId"`

// last traded price
Last fixedpoint.Value `json:"last"`

// last traded size
LastSize fixedpoint.Value `json:"lastSz"`

AskPrice fixedpoint.Value `json:"askPx"`
AskSize fixedpoint.Value `json:"askSz"`

BidPrice fixedpoint.Value `json:"bidPx"`
BidSize fixedpoint.Value `json:"bidSz"`

Open24H fixedpoint.Value `json:"open24h"`
High24H fixedpoint.Value `json:"high24H"`
Low24H fixedpoint.Value `json:"low24H"`
Volume24H fixedpoint.Value `json:"vol24h"`
VolumeCurrency24H fixedpoint.Value `json:"volCcy24h"`

// Millisecond timestamp
Timestamp types.MillisecondTimestamp `json:"ts"`
}

func (c *RestClient) MarketTicker(ctx context.Context, instId string) (*MarketTicker, error) {
// SPOT, SWAP, FUTURES, OPTION
var params = url.Values{}
params.Add("instId", instId)

req, err := c.NewRequest(ctx, "GET", "/api/v5/market/ticker", params, nil)
if err != nil {
return nil, err
}

response, err := c.SendRequest(req)
if err != nil {
return nil, err
}

var tickerResponse struct {
Code string `json:"code"`
Message string `json:"msg"`
Data []MarketTicker `json:"data"`
}
if err := response.DecodeJSON(&tickerResponse); err != nil {
return nil, err
}

if len(tickerResponse.Data) == 0 {
return nil, fmt.Errorf("ticker of %s not found", instId)
}

return &tickerResponse.Data[0], nil
}

func (c *RestClient) MarketTickers(ctx context.Context, instType InstrumentType) ([]MarketTicker, error) {
// SPOT, SWAP, FUTURES, OPTION
var params = url.Values{}
params.Add("instType", string(instType))

req, err := c.NewRequest(ctx, "GET", "/api/v5/market/tickers", params, nil)
if err != nil {
return nil, err
}

response, err := c.SendRequest(req)
if err != nil {
return nil, err
}

var tickerResponse struct {
Code string `json:"code"`
Message string `json:"msg"`
Data []MarketTicker `json:"data"`
}
if err := response.DecodeJSON(&tickerResponse); err != nil {
return nil, err
}

return tickerResponse.Data, nil
}

func Sign(payload string, secret string) string {
var sig = hmac.New(sha256.New, []byte(secret))
_, err := sig.Write([]byte(payload))
Expand Down
22 changes: 22 additions & 0 deletions pkg/exchange/okex/okexapi/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,28 @@ func TestClient_GetInstrumentsRequest(t *testing.T) {
t.Logf("instruments: %+v", instruments)
}

func TestClient_GetMarketTickers(t *testing.T) {
client := NewClient()
ctx := context.Background()
req := client.NewGetTickersRequest()

tickers, err := req.Do(ctx)
assert.NoError(t, err)
assert.NotEmpty(t, tickers)
t.Logf("tickers: %+v", tickers)
}

func TestClient_GetMarketTicker(t *testing.T) {
client := NewClient()
ctx := context.Background()
req := client.NewGetTickerRequest().InstId("BTC-USDT")

tickers, err := req.Do(ctx)
assert.NoError(t, err)
assert.NotEmpty(t, tickers)
t.Logf("tickers: %+v", tickers)
}

func TestClient_GetFundingRateRequest(t *testing.T) {
client := NewClient()
ctx := context.Background()
Expand Down
21 changes: 21 additions & 0 deletions pkg/exchange/okex/okexapi/get_ticker_request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package okexapi

import (
"github.com/c9s/requestgen"
)

//go:generate -command GetRequest requestgen -method GET -responseType .APIResponse -responseDataField Data
//go:generate -command PostRequest requestgen -method POST -responseType .APIResponse -responseDataField Data

//go:generate GetRequest -url "/api/v5/market/ticker" -type GetTickerRequest -responseDataType []MarketTicker
type GetTickerRequest struct {
client requestgen.APIClient

instId string `param:"instId,query"`
}

func (c *RestClient) NewGetTickerRequest() *GetTickerRequest {
return &GetTickerRequest{
client: c,
}
}
170 changes: 170 additions & 0 deletions pkg/exchange/okex/okexapi/get_ticker_request_requestgen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit c2e3fed

Please sign in to comment.