mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-22 06:53:52 +00:00
refactor okex to future use
This commit is contained in:
parent
2c4b6e8cd1
commit
7550ea2be1
|
@ -44,10 +44,13 @@ var rootCmd = &cobra.Command{
|
||||||
return errors.New("empty key, secret or passphrase")
|
return errors.New("empty key, secret or passphrase")
|
||||||
}
|
}
|
||||||
|
|
||||||
client := okexapi.NewClient()
|
client, err := okexapi.NewClient()
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("init client error: please check url")
|
||||||
|
}
|
||||||
client.Auth(key, secret, passphrase)
|
client.Auth(key, secret, passphrase)
|
||||||
|
|
||||||
instruments, err := client.PublicDataService.NewGetInstrumentsRequest().
|
instruments, err := client.NewGetInstrumentsRequest().
|
||||||
InstrumentType("SPOT").Do(ctx)
|
InstrumentType("SPOT").Do(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -55,14 +58,14 @@ var rootCmd = &cobra.Command{
|
||||||
|
|
||||||
log.Infof("instruments: %+v", instruments)
|
log.Infof("instruments: %+v", instruments)
|
||||||
|
|
||||||
fundingRate, err := client.PublicDataService.NewGetFundingRate().InstrumentID("BTC-USDT-SWAP").Do(ctx)
|
fundingRate, err := client.NewGetFundingRate().InstrumentID("BTC-USDT-SWAP").Do(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Infof("funding rate: %+v", fundingRate)
|
log.Infof("funding rate: %+v", fundingRate)
|
||||||
|
|
||||||
log.Infof("ACCOUNT BALANCES:")
|
log.Infof("ACCOUNT BALANCES:")
|
||||||
account, err := client.AccountBalances()
|
account, err := client.AccountBalances(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -70,7 +73,7 @@ var rootCmd = &cobra.Command{
|
||||||
log.Infof("%+v", account)
|
log.Infof("%+v", account)
|
||||||
|
|
||||||
log.Infof("ASSET BALANCES:")
|
log.Infof("ASSET BALANCES:")
|
||||||
assetBalances, err := client.AssetBalances()
|
assetBalances, err := client.AssetBalances(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -80,7 +83,7 @@ var rootCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("ASSET CURRENCIES:")
|
log.Infof("ASSET CURRENCIES:")
|
||||||
currencies, err := client.AssetCurrencies()
|
currencies, err := client.AssetCurrencies(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -90,7 +93,7 @@ var rootCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("MARKET TICKERS:")
|
log.Infof("MARKET TICKERS:")
|
||||||
tickers, err := client.MarketTickers(okexapi.InstrumentTypeSpot)
|
tickers, err := client.MarketTickers(ctx, okexapi.InstrumentTypeSpot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -99,7 +102,7 @@ var rootCmd = &cobra.Command{
|
||||||
log.Infof("%T%+v", ticker, ticker)
|
log.Infof("%T%+v", ticker, ticker)
|
||||||
}
|
}
|
||||||
|
|
||||||
ticker, err := client.MarketTicker("ETH-USDT")
|
ticker, err := client.MarketTicker(ctx, "ETH-USDT")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -107,7 +110,7 @@ var rootCmd = &cobra.Command{
|
||||||
log.Infof("%T%+v", ticker, ticker)
|
log.Infof("%T%+v", ticker, ticker)
|
||||||
|
|
||||||
log.Infof("PLACING ORDER:")
|
log.Infof("PLACING ORDER:")
|
||||||
placeResponse, err := client.TradeService.NewPlaceOrderRequest().
|
placeResponse, err := client.NewPlaceOrderRequest().
|
||||||
InstrumentID("LTC-USDT").
|
InstrumentID("LTC-USDT").
|
||||||
OrderType(okexapi.OrderTypeLimit).
|
OrderType(okexapi.OrderTypeLimit).
|
||||||
Side(okexapi.SideTypeBuy).
|
Side(okexapi.SideTypeBuy).
|
||||||
|
@ -122,7 +125,7 @@ var rootCmd = &cobra.Command{
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
log.Infof("getting order detail...")
|
log.Infof("getting order detail...")
|
||||||
orderDetail, err := client.TradeService.NewGetOrderDetailsRequest().
|
orderDetail, err := client.NewGetOrderDetailsRequest().
|
||||||
InstrumentID("LTC-USDT").
|
InstrumentID("LTC-USDT").
|
||||||
OrderID(placeResponse.OrderID).
|
OrderID(placeResponse.OrderID).
|
||||||
Do(ctx)
|
Do(ctx)
|
||||||
|
@ -132,7 +135,7 @@ var rootCmd = &cobra.Command{
|
||||||
|
|
||||||
log.Infof("order detail: %+v", orderDetail)
|
log.Infof("order detail: %+v", orderDetail)
|
||||||
|
|
||||||
cancelResponse, err := client.TradeService.NewCancelOrderRequest().
|
cancelResponse, err := client.NewCancelOrderRequest().
|
||||||
InstrumentID("LTC-USDT").
|
InstrumentID("LTC-USDT").
|
||||||
OrderID(placeResponse.OrderID).
|
OrderID(placeResponse.OrderID).
|
||||||
Do(ctx)
|
Do(ctx)
|
||||||
|
@ -144,15 +147,15 @@ var rootCmd = &cobra.Command{
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
log.Infof("BATCH PLACE ORDER:")
|
log.Infof("BATCH PLACE ORDER:")
|
||||||
batchPlaceReq := client.TradeService.NewBatchPlaceOrderRequest()
|
batchPlaceReq := client.NewBatchPlaceOrderRequest()
|
||||||
batchPlaceReq.Add(client.TradeService.NewPlaceOrderRequest().
|
batchPlaceReq.Add(client.NewPlaceOrderRequest().
|
||||||
InstrumentID("LTC-USDT").
|
InstrumentID("LTC-USDT").
|
||||||
OrderType(okexapi.OrderTypeLimit).
|
OrderType(okexapi.OrderTypeLimit).
|
||||||
Side(okexapi.SideTypeBuy).
|
Side(okexapi.SideTypeBuy).
|
||||||
Price("50.0").
|
Price("50.0").
|
||||||
Quantity("0.5"))
|
Quantity("0.5"))
|
||||||
|
|
||||||
batchPlaceReq.Add(client.TradeService.NewPlaceOrderRequest().
|
batchPlaceReq.Add(client.NewPlaceOrderRequest().
|
||||||
InstrumentID("LTC-USDT").
|
InstrumentID("LTC-USDT").
|
||||||
OrderType(okexapi.OrderTypeLimit).
|
OrderType(okexapi.OrderTypeLimit).
|
||||||
Side(okexapi.SideTypeBuy).
|
Side(okexapi.SideTypeBuy).
|
||||||
|
@ -168,7 +171,7 @@ var rootCmd = &cobra.Command{
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
log.Infof("getting pending orders...")
|
log.Infof("getting pending orders...")
|
||||||
pendingOrders, err := client.TradeService.NewGetPendingOrderRequest().Do(ctx)
|
pendingOrders, err := client.NewGetPendingOrderRequest().Do(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -176,9 +179,9 @@ var rootCmd = &cobra.Command{
|
||||||
log.Infof("pending order: %+v", pendingOrder)
|
log.Infof("pending order: %+v", pendingOrder)
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelReq := client.TradeService.NewBatchCancelOrderRequest()
|
cancelReq := client.NewBatchCancelOrderRequest()
|
||||||
for _, resp := range batchPlaceResponse {
|
for _, resp := range batchPlaceResponse {
|
||||||
cancelReq.Add(client.TradeService.NewCancelOrderRequest().
|
cancelReq.Add(client.NewCancelOrderRequest().
|
||||||
InstrumentID("LTC-USDT").
|
InstrumentID("LTC-USDT").
|
||||||
OrderID(resp.OrderID))
|
OrderID(resp.OrderID))
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ func New(n types.ExchangeName, key, secret, passphrase string) (types.ExchangeMi
|
||||||
return max.New(key, secret), nil
|
return max.New(key, secret), nil
|
||||||
|
|
||||||
case types.ExchangeOKEx:
|
case types.ExchangeOKEx:
|
||||||
return okex.New(key, secret, passphrase), nil
|
return okex.New(key, secret, passphrase)
|
||||||
|
|
||||||
case types.ExchangeKucoin:
|
case types.ExchangeKucoin:
|
||||||
return kucoin.New(key, secret, passphrase), nil
|
return kucoin.New(key, secret, passphrase), nil
|
||||||
|
|
|
@ -34,8 +34,11 @@ type Exchange struct {
|
||||||
client *okexapi.RestClient
|
client *okexapi.RestClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(key, secret, passphrase string) *Exchange {
|
func New(key, secret, passphrase string) (*Exchange, error) {
|
||||||
client := okexapi.NewClient()
|
client, err := okexapi.NewClient()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if len(key) > 0 && len(secret) > 0 {
|
if len(key) > 0 && len(secret) > 0 {
|
||||||
client.Auth(key, secret, passphrase)
|
client.Auth(key, secret, passphrase)
|
||||||
|
@ -46,7 +49,7 @@ func New(key, secret, passphrase string) *Exchange {
|
||||||
secret: secret,
|
secret: secret,
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
client: client,
|
client: client,
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Exchange) Name() types.ExchangeName {
|
func (e *Exchange) Name() types.ExchangeName {
|
||||||
|
@ -54,7 +57,7 @@ func (e *Exchange) Name() types.ExchangeName {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Exchange) QueryMarkets(ctx context.Context) (types.MarketMap, error) {
|
func (e *Exchange) QueryMarkets(ctx context.Context) (types.MarketMap, error) {
|
||||||
instruments, err := e.client.PublicDataService.NewGetInstrumentsRequest().
|
instruments, err := e.client.NewGetInstrumentsRequest().
|
||||||
InstrumentType(okexapi.InstrumentTypeSpot).
|
InstrumentType(okexapi.InstrumentTypeSpot).
|
||||||
Do(ctx)
|
Do(ctx)
|
||||||
|
|
||||||
|
@ -98,7 +101,7 @@ func (e *Exchange) QueryMarkets(ctx context.Context) (types.MarketMap, error) {
|
||||||
func (e *Exchange) QueryTicker(ctx context.Context, symbol string) (*types.Ticker, error) {
|
func (e *Exchange) QueryTicker(ctx context.Context, symbol string) (*types.Ticker, error) {
|
||||||
symbol = toLocalSymbol(symbol)
|
symbol = toLocalSymbol(symbol)
|
||||||
|
|
||||||
marketTicker, err := e.client.MarketTicker(symbol)
|
marketTicker, err := e.client.MarketTicker(ctx, symbol)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -107,7 +110,7 @@ func (e *Exchange) QueryTicker(ctx context.Context, symbol string) (*types.Ticke
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Exchange) QueryTickers(ctx context.Context, symbols ...string) (map[string]types.Ticker, error) {
|
func (e *Exchange) QueryTickers(ctx context.Context, symbols ...string) (map[string]types.Ticker, error) {
|
||||||
marketTickers, err := e.client.MarketTickers(okexapi.InstrumentTypeSpot)
|
marketTickers, err := e.client.MarketTickers(ctx, okexapi.InstrumentTypeSpot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -138,7 +141,7 @@ func (e *Exchange) PlatformFeeCurrency() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Exchange) QueryAccount(ctx context.Context) (*types.Account, error) {
|
func (e *Exchange) QueryAccount(ctx context.Context) (*types.Account, error) {
|
||||||
accountBalance, err := e.client.AccountBalances()
|
accountBalance, err := e.client.AccountBalances(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -153,7 +156,7 @@ func (e *Exchange) QueryAccount(ctx context.Context) (*types.Account, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Exchange) QueryAccountBalances(ctx context.Context) (types.BalanceMap, error) {
|
func (e *Exchange) QueryAccountBalances(ctx context.Context) (types.BalanceMap, error) {
|
||||||
accountBalances, err := e.client.AccountBalances()
|
accountBalances, err := e.client.AccountBalances(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -163,7 +166,7 @@ func (e *Exchange) QueryAccountBalances(ctx context.Context) (types.BalanceMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Exchange) SubmitOrder(ctx context.Context, order types.SubmitOrder) (*types.Order, error) {
|
func (e *Exchange) SubmitOrder(ctx context.Context, order types.SubmitOrder) (*types.Order, error) {
|
||||||
orderReq := e.client.TradeService.NewPlaceOrderRequest()
|
orderReq := e.client.NewPlaceOrderRequest()
|
||||||
|
|
||||||
orderType, err := toLocalOrderType(order.Type)
|
orderType, err := toLocalOrderType(order.Type)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -257,7 +260,7 @@ func (e *Exchange) SubmitOrder(ctx context.Context, order types.SubmitOrder) (*t
|
||||||
|
|
||||||
func (e *Exchange) QueryOpenOrders(ctx context.Context, symbol string) (orders []types.Order, err error) {
|
func (e *Exchange) QueryOpenOrders(ctx context.Context, symbol string) (orders []types.Order, err error) {
|
||||||
instrumentID := toLocalSymbol(symbol)
|
instrumentID := toLocalSymbol(symbol)
|
||||||
req := e.client.TradeService.NewGetPendingOrderRequest().InstrumentType(okexapi.InstrumentTypeSpot).InstrumentID(instrumentID)
|
req := e.client.NewGetPendingOrderRequest().InstrumentType(okexapi.InstrumentTypeSpot).InstrumentID(instrumentID)
|
||||||
orderDetails, err := req.Do(ctx)
|
orderDetails, err := req.Do(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return orders, err
|
return orders, err
|
||||||
|
@ -278,7 +281,7 @@ func (e *Exchange) CancelOrders(ctx context.Context, orders ...types.Order) erro
|
||||||
return ErrSymbolRequired
|
return ErrSymbolRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
req := e.client.TradeService.NewCancelOrderRequest()
|
req := e.client.NewCancelOrderRequest()
|
||||||
req.InstrumentID(toLocalSymbol(order.Symbol))
|
req.InstrumentID(toLocalSymbol(order.Symbol))
|
||||||
req.OrderID(strconv.FormatUint(order.OrderID, 10))
|
req.OrderID(strconv.FormatUint(order.OrderID, 10))
|
||||||
if len(order.ClientOrderID) > 0 {
|
if len(order.ClientOrderID) > 0 {
|
||||||
|
@ -287,7 +290,7 @@ func (e *Exchange) CancelOrders(ctx context.Context, orders ...types.Order) erro
|
||||||
reqs = append(reqs, req)
|
reqs = append(reqs, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
batchReq := e.client.TradeService.NewBatchCancelOrderRequest()
|
batchReq := e.client.NewBatchCancelOrderRequest()
|
||||||
batchReq.Add(reqs...)
|
batchReq.Add(reqs...)
|
||||||
_, err := batchReq.Do(ctx)
|
_, err := batchReq.Do(ctx)
|
||||||
return err
|
return err
|
||||||
|
@ -304,7 +307,7 @@ func (e *Exchange) QueryKLines(ctx context.Context, symbol string, interval type
|
||||||
|
|
||||||
intervalParam := toLocalInterval(interval.String())
|
intervalParam := toLocalInterval(interval.String())
|
||||||
|
|
||||||
req := e.client.MarketDataService.NewCandlesticksRequest(toLocalSymbol(symbol))
|
req := e.client.NewCandlesticksRequest(toLocalSymbol(symbol))
|
||||||
req.Bar(intervalParam)
|
req.Bar(intervalParam)
|
||||||
|
|
||||||
if options.StartTime != nil {
|
if options.StartTime != nil {
|
||||||
|
@ -349,7 +352,7 @@ func (e *Exchange) QueryOrder(ctx context.Context, q types.OrderQuery) (*types.O
|
||||||
if len(q.OrderID) == 0 && len(q.ClientOrderID) == 0 {
|
if len(q.OrderID) == 0 && len(q.ClientOrderID) == 0 {
|
||||||
return nil, errors.New("okex.QueryOrder: OrderId or ClientOrderId is required parameter")
|
return nil, errors.New("okex.QueryOrder: OrderId or ClientOrderId is required parameter")
|
||||||
}
|
}
|
||||||
req := e.client.TradeService.NewGetOrderDetailsRequest()
|
req := e.client.NewGetOrderDetailsRequest()
|
||||||
req.InstrumentID(q.Symbol).
|
req.InstrumentID(q.Symbol).
|
||||||
OrderID(q.OrderID).
|
OrderID(q.OrderID).
|
||||||
ClientOrderID(q.ClientOrderID)
|
ClientOrderID(q.ClientOrderID)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package okexapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
@ -14,7 +15,7 @@ import (
|
||||||
|
|
||||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||||
"github.com/c9s/bbgo/pkg/types"
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
"github.com/c9s/bbgo/pkg/util"
|
"github.com/c9s/requestgen"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -60,34 +61,26 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type RestClient struct {
|
type RestClient struct {
|
||||||
BaseURL *url.URL
|
requestgen.BaseAPIClient
|
||||||
|
|
||||||
client *http.Client
|
|
||||||
|
|
||||||
Key, Secret, Passphrase string
|
Key, Secret, Passphrase string
|
||||||
|
|
||||||
TradeService *TradeService
|
|
||||||
PublicDataService *PublicDataService
|
|
||||||
MarketDataService *MarketDataService
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient() *RestClient {
|
func NewClient() (*RestClient, error) {
|
||||||
u, err := url.Parse(RestBaseURL)
|
u, err := url.Parse(RestBaseURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
client := &RestClient{
|
client := &RestClient{
|
||||||
BaseURL: u,
|
BaseAPIClient: requestgen.BaseAPIClient{
|
||||||
client: &http.Client{
|
BaseURL: u,
|
||||||
Timeout: defaultHTTPTimeout,
|
HttpClient: &http.Client{
|
||||||
|
Timeout: defaultHTTPTimeout,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
return client, nil
|
||||||
client.TradeService = &TradeService{client: client}
|
|
||||||
client.PublicDataService = &PublicDataService{client: client}
|
|
||||||
client.MarketDataService = &MarketDataService{client: client}
|
|
||||||
return client
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RestClient) Auth(key, secret, passphrase string) {
|
func (c *RestClient) Auth(key, secret, passphrase string) {
|
||||||
|
@ -97,44 +90,8 @@ func (c *RestClient) Auth(key, secret, passphrase string) {
|
||||||
c.Passphrase = passphrase
|
c.Passphrase = passphrase
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRequest create new API request. Relative url can be provided in refURL.
|
// NewAuthenticatedRequest creates new http request for authenticated routes.
|
||||||
func (c *RestClient) newRequest(method, refURL string, params url.Values, body []byte) (*http.Request, error) {
|
func (c *RestClient) NewAuthenticatedRequest(ctx context.Context, method, refURL string, params url.Values, payload interface{}) (*http.Request, error) {
|
||||||
rel, err := url.Parse(refURL)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if params != nil {
|
|
||||||
rel.RawQuery = params.Encode()
|
|
||||||
}
|
|
||||||
|
|
||||||
pathURL := c.BaseURL.ResolveReference(rel)
|
|
||||||
return http.NewRequest(method, pathURL.String(), bytes.NewReader(body))
|
|
||||||
}
|
|
||||||
|
|
||||||
// sendRequest sends the request to the API server and handle the response
|
|
||||||
func (c *RestClient) sendRequest(req *http.Request) (*util.Response, error) {
|
|
||||||
resp, err := c.client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// newResponse reads the response body and return a new Response object
|
|
||||||
response, err := util.NewResponse(resp)
|
|
||||||
if err != nil {
|
|
||||||
return response, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check error, if there is an error, return the ErrorResponse struct type
|
|
||||||
if response.IsError() {
|
|
||||||
return response, errors.New(string(response.Body))
|
|
||||||
}
|
|
||||||
|
|
||||||
return response, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// newAuthenticatedRequest creates new http request for authenticated routes.
|
|
||||||
func (c *RestClient) newAuthenticatedRequest(method, refURL string, params url.Values, payload interface{}) (*http.Request, error) {
|
|
||||||
if len(c.Key) == 0 {
|
if len(c.Key) == 0 {
|
||||||
return nil, errors.New("empty api key")
|
return nil, errors.New("empty api key")
|
||||||
}
|
}
|
||||||
|
@ -215,13 +172,13 @@ type Account struct {
|
||||||
Details []BalanceDetail `json:"details"`
|
Details []BalanceDetail `json:"details"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RestClient) AccountBalances() (*Account, error) {
|
func (c *RestClient) AccountBalances(ctx context.Context) (*Account, error) {
|
||||||
req, err := c.newAuthenticatedRequest("GET", "/api/v5/account/balance", nil, nil)
|
req, err := c.NewAuthenticatedRequest(ctx, "GET", "/api/v5/account/balance", nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := c.sendRequest(req)
|
response, err := c.SendRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -252,13 +209,13 @@ type AssetBalance struct {
|
||||||
|
|
||||||
type AssetBalanceList []AssetBalance
|
type AssetBalanceList []AssetBalance
|
||||||
|
|
||||||
func (c *RestClient) AssetBalances() (AssetBalanceList, error) {
|
func (c *RestClient) AssetBalances(ctx context.Context) (AssetBalanceList, error) {
|
||||||
req, err := c.newAuthenticatedRequest("GET", "/api/v5/asset/balances", nil, nil)
|
req, err := c.NewAuthenticatedRequest(ctx, "GET", "/api/v5/asset/balances", nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := c.sendRequest(req)
|
response, err := c.SendRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -287,13 +244,13 @@ type AssetCurrency struct {
|
||||||
MinWithdrawalThreshold fixedpoint.Value `json:"minWd"`
|
MinWithdrawalThreshold fixedpoint.Value `json:"minWd"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RestClient) AssetCurrencies() ([]AssetCurrency, error) {
|
func (c *RestClient) AssetCurrencies(ctx context.Context) ([]AssetCurrency, error) {
|
||||||
req, err := c.newAuthenticatedRequest("GET", "/api/v5/asset/currencies", nil, nil)
|
req, err := c.NewAuthenticatedRequest(ctx, "GET", "/api/v5/asset/currencies", nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := c.sendRequest(req)
|
response, err := c.SendRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -337,17 +294,17 @@ type MarketTicker struct {
|
||||||
Timestamp types.MillisecondTimestamp `json:"ts"`
|
Timestamp types.MillisecondTimestamp `json:"ts"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RestClient) MarketTicker(instId string) (*MarketTicker, error) {
|
func (c *RestClient) MarketTicker(ctx context.Context, instId string) (*MarketTicker, error) {
|
||||||
// SPOT, SWAP, FUTURES, OPTION
|
// SPOT, SWAP, FUTURES, OPTION
|
||||||
var params = url.Values{}
|
var params = url.Values{}
|
||||||
params.Add("instId", instId)
|
params.Add("instId", instId)
|
||||||
|
|
||||||
req, err := c.newRequest("GET", "/api/v5/market/ticker", params, nil)
|
req, err := c.NewRequest(ctx, "GET", "/api/v5/market/ticker", params, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := c.sendRequest(req)
|
response, err := c.SendRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -368,17 +325,17 @@ func (c *RestClient) MarketTicker(instId string) (*MarketTicker, error) {
|
||||||
return &tickerResponse.Data[0], nil
|
return &tickerResponse.Data[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RestClient) MarketTickers(instType InstrumentType) ([]MarketTicker, error) {
|
func (c *RestClient) MarketTickers(ctx context.Context, instType InstrumentType) ([]MarketTicker, error) {
|
||||||
// SPOT, SWAP, FUTURES, OPTION
|
// SPOT, SWAP, FUTURES, OPTION
|
||||||
var params = url.Values{}
|
var params = url.Values{}
|
||||||
params.Add("instType", string(instType))
|
params.Add("instType", string(instType))
|
||||||
|
|
||||||
req, err := c.newRequest("GET", "/api/v5/market/tickers", params, nil)
|
req, err := c.NewRequest(ctx, "GET", "/api/v5/market/tickers", params, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := c.sendRequest(req)
|
response, err := c.SendRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -405,3 +362,9 @@ func Sign(payload string, secret string) string {
|
||||||
return base64.StdEncoding.EncodeToString(sig.Sum(nil))
|
return base64.StdEncoding.EncodeToString(sig.Sum(nil))
|
||||||
// return hex.EncodeToString(sig.Sum(nil))
|
// return hex.EncodeToString(sig.Sum(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type APIResponse struct {
|
||||||
|
Code string `json:"code"`
|
||||||
|
Message string `json:"msg"`
|
||||||
|
Data json.RawMessage `json:"data"`
|
||||||
|
}
|
||||||
|
|
|
@ -22,17 +22,17 @@ func getTestClientOrSkip(t *testing.T) *RestClient {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
client := NewClient()
|
client, err := NewClient()
|
||||||
|
assert.NoError(t, err)
|
||||||
client.Auth(key, secret, passphrase)
|
client.Auth(key, secret, passphrase)
|
||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClient_GetInstrumentsRequest(t *testing.T) {
|
func TestClient_GetInstrumentsRequest(t *testing.T) {
|
||||||
client := NewClient()
|
client, err := NewClient()
|
||||||
|
assert.NoError(t, err)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
req := client.NewGetInstrumentsRequest()
|
||||||
srv := &PublicDataService{client: client}
|
|
||||||
req := srv.NewGetInstrumentsRequest()
|
|
||||||
|
|
||||||
instruments, err := req.
|
instruments, err := req.
|
||||||
InstrumentType(InstrumentTypeSpot).
|
InstrumentType(InstrumentTypeSpot).
|
||||||
|
@ -43,10 +43,10 @@ func TestClient_GetInstrumentsRequest(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClient_GetFundingRateRequest(t *testing.T) {
|
func TestClient_GetFundingRateRequest(t *testing.T) {
|
||||||
client := NewClient()
|
client, err := NewClient()
|
||||||
|
assert.NoError(t, err)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
srv := &PublicDataService{client: client}
|
req := client.NewGetFundingRate()
|
||||||
req := srv.NewGetFundingRate()
|
|
||||||
|
|
||||||
instrument, err := req.
|
instrument, err := req.
|
||||||
InstrumentID("BTC-USDT-SWAP").
|
InstrumentID("BTC-USDT-SWAP").
|
||||||
|
@ -59,8 +59,7 @@ func TestClient_GetFundingRateRequest(t *testing.T) {
|
||||||
func TestClient_PlaceOrderRequest(t *testing.T) {
|
func TestClient_PlaceOrderRequest(t *testing.T) {
|
||||||
client := getTestClientOrSkip(t)
|
client := getTestClientOrSkip(t)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
srv := &TradeService{client: client}
|
req := client.NewPlaceOrderRequest()
|
||||||
req := srv.NewPlaceOrderRequest()
|
|
||||||
|
|
||||||
order, err := req.
|
order, err := req.
|
||||||
InstrumentID("BTC-USDT").
|
InstrumentID("BTC-USDT").
|
||||||
|
@ -78,8 +77,7 @@ func TestClient_PlaceOrderRequest(t *testing.T) {
|
||||||
func TestClient_GetPendingOrderRequest(t *testing.T) {
|
func TestClient_GetPendingOrderRequest(t *testing.T) {
|
||||||
client := getTestClientOrSkip(t)
|
client := getTestClientOrSkip(t)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
srv := &TradeService{client: client}
|
req := client.NewGetPendingOrderRequest()
|
||||||
req := srv.NewGetPendingOrderRequest()
|
|
||||||
odr_type := []string{string(OrderTypeLimit), string(OrderTypeIOC)}
|
odr_type := []string{string(OrderTypeLimit), string(OrderTypeIOC)}
|
||||||
|
|
||||||
pending_order, err := req.
|
pending_order, err := req.
|
||||||
|
@ -94,8 +92,7 @@ func TestClient_GetPendingOrderRequest(t *testing.T) {
|
||||||
func TestClient_GetOrderDetailsRequest(t *testing.T) {
|
func TestClient_GetOrderDetailsRequest(t *testing.T) {
|
||||||
client := getTestClientOrSkip(t)
|
client := getTestClientOrSkip(t)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
srv := &TradeService{client: client}
|
req := client.NewGetOrderDetailsRequest()
|
||||||
req := srv.NewGetOrderDetailsRequest()
|
|
||||||
|
|
||||||
orderDetail, err := req.
|
orderDetail, err := req.
|
||||||
InstrumentID("BTC-USDT").
|
InstrumentID("BTC-USDT").
|
||||||
|
|
|
@ -2,6 +2,7 @@ package okexapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -82,29 +83,29 @@ func (r *CandlesticksRequest) Do(ctx context.Context) ([]Candle, error) {
|
||||||
params.Add("limit", strconv.Itoa(*r.limit))
|
params.Add("limit", strconv.Itoa(*r.limit))
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := r.client.newRequest("GET", "/api/v5/market/candles", params, nil)
|
req, err := r.client.NewRequest(ctx, "GET", "/api/v5/market/candles", params, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := r.client.sendRequest(req)
|
response, err := r.client.SendRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
type candleEntry [7]string
|
type candleEntry [7]string
|
||||||
var candlesResponse struct {
|
|
||||||
Code string `json:"code"`
|
|
||||||
Message string `json:"msg"`
|
|
||||||
Data []candleEntry `json:"data"`
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := resp.DecodeJSON(&candlesResponse); err != nil {
|
var apiResponse APIResponse
|
||||||
|
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var data []candleEntry
|
||||||
|
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var candles []Candle
|
var candles []Candle
|
||||||
for _, entry := range candlesResponse.Data {
|
for _, entry := range data {
|
||||||
timestamp, err := strconv.ParseInt(entry[0], 10, 64)
|
timestamp, err := strconv.ParseInt(entry[0], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return candles, err
|
return candles, err
|
||||||
|
@ -177,27 +178,26 @@ func (r *MarketTickersRequest) Do(ctx context.Context) ([]MarketTicker, error) {
|
||||||
var params = url.Values{}
|
var params = url.Values{}
|
||||||
params.Add("instType", string(r.instType))
|
params.Add("instType", string(r.instType))
|
||||||
|
|
||||||
req, err := r.client.newRequest("GET", "/api/v5/market/tickers", params, nil)
|
req, err := r.client.NewRequest(ctx, "GET", "/api/v5/market/tickers", params, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := r.client.sendRequest(req)
|
response, err := r.client.SendRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tickerResponse struct {
|
var apiResponse APIResponse
|
||||||
Code string `json:"code"`
|
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||||
Message string `json:"msg"`
|
return nil, err
|
||||||
Data []MarketTicker `json:"data"`
|
|
||||||
}
|
}
|
||||||
|
var data []MarketTicker
|
||||||
if err := response.DecodeJSON(&tickerResponse); err != nil {
|
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return tickerResponse.Data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type MarketTickerRequest struct {
|
type MarketTickerRequest struct {
|
||||||
|
@ -216,53 +216,49 @@ func (r *MarketTickerRequest) Do(ctx context.Context) (*MarketTicker, error) {
|
||||||
var params = url.Values{}
|
var params = url.Values{}
|
||||||
params.Add("instId", r.instId)
|
params.Add("instId", r.instId)
|
||||||
|
|
||||||
req, err := r.client.newRequest("GET", "/api/v5/market/ticker", params, nil)
|
req, err := r.client.NewRequest(ctx, "GET", "/api/v5/market/ticker", params, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := r.client.sendRequest(req)
|
response, err := r.client.SendRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tickerResponse struct {
|
var apiResponse APIResponse
|
||||||
Code string `json:"code"`
|
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||||
Message string `json:"msg"`
|
return nil, err
|
||||||
Data []MarketTicker `json:"data"`
|
|
||||||
}
|
}
|
||||||
if err := response.DecodeJSON(&tickerResponse); err != nil {
|
var data []MarketTicker
|
||||||
|
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(tickerResponse.Data) == 0 {
|
if len(data) == 0 {
|
||||||
return nil, fmt.Errorf("ticker of %s not found", r.instId)
|
return nil, fmt.Errorf("ticker of %s not found", r.instId)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &tickerResponse.Data[0], nil
|
return &data[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type MarketDataService struct {
|
func (c *RestClient) NewMarketTickerRequest(instId string) *MarketTickerRequest {
|
||||||
client *RestClient
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *MarketDataService) NewMarketTickerRequest(instId string) *MarketTickerRequest {
|
|
||||||
return &MarketTickerRequest{
|
return &MarketTickerRequest{
|
||||||
client: c.client,
|
client: c,
|
||||||
instId: instId,
|
instId: instId,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MarketDataService) NewMarketTickersRequest(instType string) *MarketTickersRequest {
|
func (c *RestClient) NewMarketTickersRequest(instType string) *MarketTickersRequest {
|
||||||
return &MarketTickersRequest{
|
return &MarketTickersRequest{
|
||||||
client: c.client,
|
client: c,
|
||||||
instType: instType,
|
instType: instType,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MarketDataService) NewCandlesticksRequest(instId string) *CandlesticksRequest {
|
func (c *RestClient) NewCandlesticksRequest(instId string) *CandlesticksRequest {
|
||||||
return &CandlesticksRequest{
|
return &CandlesticksRequest{
|
||||||
client: c.client,
|
client: c,
|
||||||
instId: instId,
|
instId: instId,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package okexapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||||
|
@ -9,19 +10,15 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PublicDataService struct {
|
func (s *RestClient) NewGetInstrumentsRequest() *GetInstrumentsRequest {
|
||||||
client *RestClient
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PublicDataService) NewGetInstrumentsRequest() *GetInstrumentsRequest {
|
|
||||||
return &GetInstrumentsRequest{
|
return &GetInstrumentsRequest{
|
||||||
client: s.client,
|
client: s,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublicDataService) NewGetFundingRate() *GetFundingRateRequest {
|
func (s *RestClient) NewGetFundingRate() *GetFundingRateRequest {
|
||||||
return &GetFundingRateRequest{
|
return &GetFundingRateRequest{
|
||||||
client: s.client,
|
client: s,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,30 +46,30 @@ func (r *GetFundingRateRequest) Do(ctx context.Context) (*FundingRate, error) {
|
||||||
var params = url.Values{}
|
var params = url.Values{}
|
||||||
params.Add("instId", string(r.instId))
|
params.Add("instId", string(r.instId))
|
||||||
|
|
||||||
req, err := r.client.newRequest("GET", "/api/v5/public/funding-rate", params, nil)
|
req, err := r.client.NewRequest(ctx, "GET", "/api/v5/public/funding-rate", params, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := r.client.sendRequest(req)
|
response, err := r.client.SendRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var apiResponse struct {
|
var apiResponse APIResponse
|
||||||
Code string `json:"code"`
|
|
||||||
Message string `json:"msg"`
|
|
||||||
Data []FundingRate `json:"data"`
|
|
||||||
}
|
|
||||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
var data []FundingRate
|
||||||
|
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if len(apiResponse.Data) == 0 {
|
if len(data) == 0 {
|
||||||
return nil, errors.New("empty funding rate data")
|
return nil, errors.New("empty funding rate data")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &apiResponse.Data[0], nil
|
return &data[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Instrument struct {
|
type Instrument struct {
|
||||||
|
@ -123,24 +120,24 @@ func (r *GetInstrumentsRequest) Do(ctx context.Context) ([]Instrument, error) {
|
||||||
params.Add("instId", *r.instId)
|
params.Add("instId", *r.instId)
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := r.client.newRequest("GET", "/api/v5/public/instruments", params, nil)
|
req, err := r.client.NewRequest(ctx, "GET", "/api/v5/public/instruments", params, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := r.client.sendRequest(req)
|
response, err := r.client.SendRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var apiResponse struct {
|
var apiResponse APIResponse
|
||||||
Code string `json:"code"`
|
|
||||||
Message string `json:"msg"`
|
|
||||||
Data []Instrument `json:"data"`
|
|
||||||
}
|
|
||||||
if err := response.DecodeJSON(&apiResponse); err != nil {
|
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
var data []Instrument
|
||||||
|
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return apiResponse.Data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package okexapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -10,10 +11,6 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TradeService struct {
|
|
||||||
client *RestClient
|
|
||||||
}
|
|
||||||
|
|
||||||
type OrderResponse struct {
|
type OrderResponse struct {
|
||||||
OrderID string `json:"ordId"`
|
OrderID string `json:"ordId"`
|
||||||
ClientOrderID string `json:"clOrdId"`
|
ClientOrderID string `json:"clOrdId"`
|
||||||
|
@ -22,45 +19,45 @@ type OrderResponse struct {
|
||||||
Message string `json:"sMsg"`
|
Message string `json:"sMsg"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TradeService) NewPlaceOrderRequest() *PlaceOrderRequest {
|
func (c *RestClient) NewPlaceOrderRequest() *PlaceOrderRequest {
|
||||||
return &PlaceOrderRequest{
|
return &PlaceOrderRequest{
|
||||||
client: c.client,
|
client: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TradeService) NewBatchPlaceOrderRequest() *BatchPlaceOrderRequest {
|
func (c *RestClient) NewBatchPlaceOrderRequest() *BatchPlaceOrderRequest {
|
||||||
return &BatchPlaceOrderRequest{
|
return &BatchPlaceOrderRequest{
|
||||||
client: c.client,
|
client: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TradeService) NewCancelOrderRequest() *CancelOrderRequest {
|
func (c *RestClient) NewCancelOrderRequest() *CancelOrderRequest {
|
||||||
return &CancelOrderRequest{
|
return &CancelOrderRequest{
|
||||||
client: c.client,
|
client: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TradeService) NewBatchCancelOrderRequest() *BatchCancelOrderRequest {
|
func (c *RestClient) NewBatchCancelOrderRequest() *BatchCancelOrderRequest {
|
||||||
return &BatchCancelOrderRequest{
|
return &BatchCancelOrderRequest{
|
||||||
client: c.client,
|
client: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TradeService) NewGetOrderDetailsRequest() *GetOrderDetailsRequest {
|
func (c *RestClient) NewGetOrderDetailsRequest() *GetOrderDetailsRequest {
|
||||||
return &GetOrderDetailsRequest{
|
return &GetOrderDetailsRequest{
|
||||||
client: c.client,
|
client: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TradeService) NewGetPendingOrderRequest() *GetPendingOrderRequest {
|
func (c *RestClient) NewGetPendingOrderRequest() *GetPendingOrderRequest {
|
||||||
return &GetPendingOrderRequest{
|
return &GetPendingOrderRequest{
|
||||||
client: c.client,
|
client: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TradeService) NewGetTransactionDetailsRequest() *GetTransactionDetailsRequest {
|
func (c *RestClient) NewGetTransactionDetailsRequest() *GetTransactionDetailsRequest {
|
||||||
return &GetTransactionDetailsRequest{
|
return &GetTransactionDetailsRequest{
|
||||||
client: c.client,
|
client: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,30 +96,30 @@ func (r *PlaceOrderRequest) Parameters() map[string]interface{} {
|
||||||
|
|
||||||
func (r *PlaceOrderRequest) Do(ctx context.Context) (*OrderResponse, error) {
|
func (r *PlaceOrderRequest) Do(ctx context.Context) (*OrderResponse, error) {
|
||||||
payload := r.Parameters()
|
payload := r.Parameters()
|
||||||
req, err := r.client.newAuthenticatedRequest("POST", "/api/v5/trade/order", nil, payload)
|
req, err := r.client.NewAuthenticatedRequest(ctx, "POST", "/api/v5/trade/order", nil, payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := r.client.sendRequest(req)
|
response, err := r.client.SendRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var orderResponse struct {
|
var apiResponse APIResponse
|
||||||
Code string `json:"code"`
|
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||||
Message string `json:"msg"`
|
return nil, err
|
||||||
Data []OrderResponse `json:"data"`
|
|
||||||
}
|
}
|
||||||
if err := response.DecodeJSON(&orderResponse); err != nil {
|
var data []OrderResponse
|
||||||
|
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(orderResponse.Data) == 0 {
|
if len(data) == 0 {
|
||||||
return nil, errors.New("order create error")
|
return nil, errors.New("order create error")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &orderResponse.Data[0], nil
|
return &data[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:generate requestgen -type CancelOrderRequest
|
//go:generate requestgen -type CancelOrderRequest
|
||||||
|
@ -149,26 +146,26 @@ func (r *CancelOrderRequest) Do(ctx context.Context) ([]OrderResponse, error) {
|
||||||
return nil, errors.New("either orderID or clientOrderID is required for canceling order")
|
return nil, errors.New("either orderID or clientOrderID is required for canceling order")
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := r.client.newAuthenticatedRequest("POST", "/api/v5/trade/cancel-order", nil, payload)
|
req, err := r.client.NewAuthenticatedRequest(ctx, "POST", "/api/v5/trade/cancel-order", nil, payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := r.client.sendRequest(req)
|
response, err := r.client.SendRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var orderResponse struct {
|
var apiResponse APIResponse
|
||||||
Code string `json:"code"`
|
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||||
Message string `json:"msg"`
|
return nil, err
|
||||||
Data []OrderResponse `json:"data"`
|
|
||||||
}
|
}
|
||||||
if err := response.DecodeJSON(&orderResponse); err != nil {
|
var data []OrderResponse
|
||||||
|
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return orderResponse.Data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type BatchCancelOrderRequest struct {
|
type BatchCancelOrderRequest struct {
|
||||||
|
@ -190,26 +187,26 @@ func (r *BatchCancelOrderRequest) Do(ctx context.Context) ([]OrderResponse, erro
|
||||||
parameterList = append(parameterList, params)
|
parameterList = append(parameterList, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := r.client.newAuthenticatedRequest("POST", "/api/v5/trade/cancel-batch-orders", nil, parameterList)
|
req, err := r.client.NewAuthenticatedRequest(ctx, "POST", "/api/v5/trade/cancel-batch-orders", nil, parameterList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := r.client.sendRequest(req)
|
response, err := r.client.SendRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var orderResponse struct {
|
var apiResponse APIResponse
|
||||||
Code string `json:"code"`
|
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||||
Message string `json:"msg"`
|
return nil, err
|
||||||
Data []OrderResponse `json:"data"`
|
|
||||||
}
|
}
|
||||||
if err := response.DecodeJSON(&orderResponse); err != nil {
|
var data []OrderResponse
|
||||||
|
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return orderResponse.Data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type BatchPlaceOrderRequest struct {
|
type BatchPlaceOrderRequest struct {
|
||||||
|
@ -231,26 +228,26 @@ func (r *BatchPlaceOrderRequest) Do(ctx context.Context) ([]OrderResponse, error
|
||||||
parameterList = append(parameterList, params)
|
parameterList = append(parameterList, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := r.client.newAuthenticatedRequest("POST", "/api/v5/trade/batch-orders", nil, parameterList)
|
req, err := r.client.NewAuthenticatedRequest(ctx, "POST", "/api/v5/trade/batch-orders", nil, parameterList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := r.client.sendRequest(req)
|
response, err := r.client.SendRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var orderResponse struct {
|
var apiResponse APIResponse
|
||||||
Code string `json:"code"`
|
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||||
Message string `json:"msg"`
|
return nil, err
|
||||||
Data []OrderResponse `json:"data"`
|
|
||||||
}
|
}
|
||||||
if err := response.DecodeJSON(&orderResponse); err != nil {
|
var data []OrderResponse
|
||||||
|
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return orderResponse.Data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type OrderDetails struct {
|
type OrderDetails struct {
|
||||||
|
@ -343,30 +340,30 @@ func (r *GetOrderDetailsRequest) QueryParameters() url.Values {
|
||||||
|
|
||||||
func (r *GetOrderDetailsRequest) Do(ctx context.Context) (*OrderDetails, error) {
|
func (r *GetOrderDetailsRequest) Do(ctx context.Context) (*OrderDetails, error) {
|
||||||
params := r.QueryParameters()
|
params := r.QueryParameters()
|
||||||
req, err := r.client.newAuthenticatedRequest("GET", "/api/v5/trade/order", params, nil)
|
req, err := r.client.NewAuthenticatedRequest(ctx, "GET", "/api/v5/trade/order", params, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := r.client.sendRequest(req)
|
response, err := r.client.SendRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var orderResponse struct {
|
var apiResponse APIResponse
|
||||||
Code string `json:"code"`
|
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||||
Message string `json:"msg"`
|
return nil, err
|
||||||
Data []OrderDetails `json:"data"`
|
|
||||||
}
|
}
|
||||||
if err := response.DecodeJSON(&orderResponse); err != nil {
|
var data []OrderDetails
|
||||||
|
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(orderResponse.Data) == 0 {
|
if len(data) == 0 {
|
||||||
return nil, errors.New("get order details error")
|
return nil, errors.New("get order details error")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &orderResponse.Data[0], nil
|
return &data[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetPendingOrderRequest struct {
|
type GetPendingOrderRequest struct {
|
||||||
|
@ -430,26 +427,26 @@ func (r *GetPendingOrderRequest) Parameters() map[string]interface{} {
|
||||||
|
|
||||||
func (r *GetPendingOrderRequest) Do(ctx context.Context) ([]OrderDetails, error) {
|
func (r *GetPendingOrderRequest) Do(ctx context.Context) ([]OrderDetails, error) {
|
||||||
payload := r.Parameters()
|
payload := r.Parameters()
|
||||||
req, err := r.client.newAuthenticatedRequest("GET", "/api/v5/trade/orders-pending", nil, payload)
|
req, err := r.client.NewAuthenticatedRequest(ctx, "GET", "/api/v5/trade/orders-pending", nil, payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := r.client.sendRequest(req)
|
response, err := r.client.SendRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var orderResponse struct {
|
var apiResponse APIResponse
|
||||||
Code string `json:"code"`
|
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||||
Message string `json:"msg"`
|
return nil, err
|
||||||
Data []OrderDetails `json:"data"`
|
|
||||||
}
|
}
|
||||||
if err := response.DecodeJSON(&orderResponse); err != nil {
|
var data []OrderDetails
|
||||||
|
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return orderResponse.Data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetTransactionDetailsRequest struct {
|
type GetTransactionDetailsRequest struct {
|
||||||
|
@ -497,24 +494,24 @@ func (r *GetTransactionDetailsRequest) Parameters() map[string]interface{} {
|
||||||
|
|
||||||
func (r *GetTransactionDetailsRequest) Do(ctx context.Context) ([]OrderDetails, error) {
|
func (r *GetTransactionDetailsRequest) Do(ctx context.Context) ([]OrderDetails, error) {
|
||||||
payload := r.Parameters()
|
payload := r.Parameters()
|
||||||
req, err := r.client.newAuthenticatedRequest("GET", "/api/v5/trade/fills", nil, payload)
|
req, err := r.client.NewAuthenticatedRequest(ctx, "GET", "/api/v5/trade/fills", nil, payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := r.client.sendRequest(req)
|
response, err := r.client.SendRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var orderResponse struct {
|
var apiResponse APIResponse
|
||||||
Code string `json:"code"`
|
if err := response.DecodeJSON(&apiResponse); err != nil {
|
||||||
Message string `json:"msg"`
|
return nil, err
|
||||||
Data []OrderDetails `json:"data"`
|
|
||||||
}
|
}
|
||||||
if err := response.DecodeJSON(&orderResponse); err != nil {
|
var data []OrderDetails
|
||||||
|
if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return orderResponse.Data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,8 @@ func Test_QueryOrder(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
e := New(key, secret, passphrase)
|
e, err := New(key, secret, passphrase)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
queryOrder := types.OrderQuery{
|
queryOrder := types.OrderQuery{
|
||||||
Symbol: "BTC-USDT",
|
Symbol: "BTC-USDT",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user