From cba9ffe064aef6397df0b3a433ef7a60b00b0ba7 Mon Sep 17 00:00:00 2001 From: c9s Date: Fri, 5 Aug 2022 11:20:55 +0800 Subject: [PATCH] exchange/max: add order trades api --- pkg/exchange/max/exchange.go | 27 +++ .../max/maxapi/v3/get_order_trades_request.go | 19 ++ .../v3/get_order_trades_request_requestgen.go | 165 ++++++++++++++++++ 3 files changed, 211 insertions(+) create mode 100644 pkg/exchange/max/maxapi/v3/get_order_trades_request.go create mode 100644 pkg/exchange/max/maxapi/v3/get_order_trades_request_requestgen.go diff --git a/pkg/exchange/max/exchange.go b/pkg/exchange/max/exchange.go index 264044bc8..339086b59 100644 --- a/pkg/exchange/max/exchange.go +++ b/pkg/exchange/max/exchange.go @@ -168,6 +168,33 @@ func (e *Exchange) NewStream() types.Stream { return stream } +func (e *Exchange) QueryOrderTrades(ctx context.Context, q types.OrderQuery) ([]types.Trade, error) { + orderID, err := strconv.ParseInt(q.OrderID, 10, 64) + if err != nil { + return nil, err + } + + maxTrades, err := e.v3order.NewGetOrderTradesRequest().Id(uint64(orderID)).Do(ctx) + if err != nil { + return nil, err + } + + var trades []types.Trade + for _, t := range maxTrades { + localTrade, err := toGlobalTrade(t) + if err != nil { + log.WithError(err).Errorf("can not convert trade: %+v", t) + continue + } + + trades = append(trades, *localTrade) + } + + // ensure everything is sorted ascending + trades = types.SortTradesAscending(trades) + return trades, nil +} + func (e *Exchange) QueryOrder(ctx context.Context, q types.OrderQuery) (*types.Order, error) { orderID, err := strconv.ParseInt(q.OrderID, 10, 64) if err != nil { diff --git a/pkg/exchange/max/maxapi/v3/get_order_trades_request.go b/pkg/exchange/max/maxapi/v3/get_order_trades_request.go new file mode 100644 index 000000000..b0c5d8343 --- /dev/null +++ b/pkg/exchange/max/maxapi/v3/get_order_trades_request.go @@ -0,0 +1,19 @@ +package v3 + +//go:generate -command GetRequest requestgen -method GET +//go:generate -command PostRequest requestgen -method POST +//go:generate -command DeleteRequest requestgen -method DELETE + +import "github.com/c9s/requestgen" + +func (s *OrderService) NewGetOrderTradesRequest() *GetOrderTradesRequest { + return &GetOrderTradesRequest{client: s.Client} +} + +//go:generate GetRequest -url "/api/v3/order/trades" -type GetOrderTradesRequest -responseType []Trade +type GetOrderTradesRequest struct { + client requestgen.AuthenticatedAPIClient + + id *uint64 `param:"id,omitempty"` + clientOrderID *string `param:"client_oid,omitempty"` +} diff --git a/pkg/exchange/max/maxapi/v3/get_order_trades_request_requestgen.go b/pkg/exchange/max/maxapi/v3/get_order_trades_request_requestgen.go new file mode 100644 index 000000000..6ff35f863 --- /dev/null +++ b/pkg/exchange/max/maxapi/v3/get_order_trades_request_requestgen.go @@ -0,0 +1,165 @@ +// Code generated by "requestgen -method GET -url /api/v3/order/trades -type GetOrderTradesRequest -responseType []Trade"; DO NOT EDIT. + +package v3 + +import ( + "context" + "encoding/json" + "fmt" + "github.com/c9s/bbgo/pkg/exchange/max/maxapi" + "net/url" + "reflect" + "regexp" +) + +func (g *GetOrderTradesRequest) Id(id uint64) *GetOrderTradesRequest { + g.id = &id + return g +} + +func (g *GetOrderTradesRequest) ClientOrderID(clientOrderID string) *GetOrderTradesRequest { + g.clientOrderID = &clientOrderID + return g +} + +// GetQueryParameters builds and checks the query parameters and returns url.Values +func (g *GetOrderTradesRequest) GetQueryParameters() (url.Values, error) { + var params = map[string]interface{}{} + + query := url.Values{} + for _k, _v := range params { + query.Add(_k, fmt.Sprintf("%v", _v)) + } + + return query, nil +} + +// GetParameters builds and checks the parameters and return the result in a map object +func (g *GetOrderTradesRequest) GetParameters() (map[string]interface{}, error) { + var params = map[string]interface{}{} + // check id field -> json key id + if g.id != nil { + id := *g.id + + // assign parameter of id + params["id"] = id + } else { + } + // check clientOrderID field -> json key client_oid + if g.clientOrderID != nil { + clientOrderID := *g.clientOrderID + + // assign parameter of clientOrderID + params["client_oid"] = clientOrderID + } else { + } + + return params, nil +} + +// GetParametersQuery converts the parameters from GetParameters into the url.Values format +func (g *GetOrderTradesRequest) GetParametersQuery() (url.Values, error) { + query := url.Values{} + + params, err := g.GetParameters() + if err != nil { + return query, err + } + + for _k, _v := range params { + if g.isVarSlice(_v) { + g.iterateSlice(_v, func(it interface{}) { + query.Add(_k+"[]", fmt.Sprintf("%v", it)) + }) + } else { + query.Add(_k, fmt.Sprintf("%v", _v)) + } + } + + return query, nil +} + +// GetParametersJSON converts the parameters from GetParameters into the JSON format +func (g *GetOrderTradesRequest) GetParametersJSON() ([]byte, error) { + params, err := g.GetParameters() + if err != nil { + return nil, err + } + + return json.Marshal(params) +} + +// GetSlugParameters builds and checks the slug parameters and return the result in a map object +func (g *GetOrderTradesRequest) GetSlugParameters() (map[string]interface{}, error) { + var params = map[string]interface{}{} + + return params, nil +} + +func (g *GetOrderTradesRequest) applySlugsToUrl(url string, slugs map[string]string) string { + for _k, _v := range slugs { + needleRE := regexp.MustCompile(":" + _k + "\\b") + url = needleRE.ReplaceAllString(url, _v) + } + + return url +} + +func (g *GetOrderTradesRequest) iterateSlice(slice interface{}, _f func(it interface{})) { + sliceValue := reflect.ValueOf(slice) + for _i := 0; _i < sliceValue.Len(); _i++ { + it := sliceValue.Index(_i).Interface() + _f(it) + } +} + +func (g *GetOrderTradesRequest) isVarSlice(_v interface{}) bool { + rt := reflect.TypeOf(_v) + switch rt.Kind() { + case reflect.Slice: + return true + } + return false +} + +func (g *GetOrderTradesRequest) GetSlugsMap() (map[string]string, error) { + slugs := map[string]string{} + params, err := g.GetSlugParameters() + if err != nil { + return slugs, nil + } + + for _k, _v := range params { + slugs[_k] = fmt.Sprintf("%v", _v) + } + + return slugs, nil +} + +func (g *GetOrderTradesRequest) Do(ctx context.Context) ([]max.Trade, error) { + + // empty params for GET operation + var params interface{} + query, err := g.GetParametersQuery() + if err != nil { + return nil, err + } + + apiURL := "/api/v3/order/trades" + + req, err := g.client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params) + if err != nil { + return nil, err + } + + response, err := g.client.SendRequest(req) + if err != nil { + return nil, err + } + + var apiResponse []max.Trade + if err := response.DecodeJSON(&apiResponse); err != nil { + return nil, err + } + return apiResponse, nil +}