diff --git a/bybit_api_client.go b/bybit_api_client.go index 76581b3..b672b51 100644 --- a/bybit_api_client.go +++ b/bybit_api_client.go @@ -25,9 +25,6 @@ type ServerResponse struct { Time int64 `json:"time"` } -// TimeInForceType define time in force type of order -type TimeInForceType string - // Client define API client type Client struct { APIKey string @@ -245,7 +242,7 @@ func (c *Client) NewPlaceOrderService(category, symbol, side, orderType, qty str } } -func (c *Client) NewPlaceTradeService(params map[string]interface{}) *Trade { +func (c *Client) NewTradeService(params map[string]interface{}) *Trade { return &Trade{ c: c, params: params, diff --git a/examples/Trade/place_batch_trade.go b/examples/Trade/place_batch_trade.go new file mode 100644 index 0000000..bae2836 --- /dev/null +++ b/examples/Trade/place_batch_trade.go @@ -0,0 +1,51 @@ +package main + +import ( + "context" + "fmt" + bybit "github.com/wuhewuhe/bybit.go.api" +) + +func main() { + PlaceBatchTrade() +} + +func PlaceBatchTrade() { + client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) + params := map[string]interface{}{"category": "option", + "request": []map[string]interface{}{ + { + "category": "option", + "symbol": "BTC-10FEB23-24000-C", + "orderType": "Limit", + "side": "Buy", + "qty": "0.1", + "price": "5", + "orderIv": "0.1", + "timeInForce": "GTC", + "orderLinkId": "9b381bb1-401", + "mmp": false, + "reduceOnly": false, + }, + { + "category": "option", + "symbol": "BTC-10FEB23-24000-C", + "orderType": "Limit", + "side": "Buy", + "qty": "0.1", + "price": "5", + "orderIv": "0.1", + "timeInForce": "GTC", + "orderLinkId": "82ee86dd-001", + "mmp": false, + "reduceOnly": false, + }, + }, + } + orderResult, err := client.NewTradeService(params).PlaceBatchOrder(context.Background()) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(bybit.PrettyPrint(orderResult)) +} diff --git a/examples/Trade/place_trade.go b/examples/Trade/place_trade.go index 4da2bb4..5558d4f 100644 --- a/examples/Trade/place_trade.go +++ b/examples/Trade/place_trade.go @@ -13,7 +13,7 @@ func main() { func PlaceTrade() { client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) params := map[string]interface{}{"category": "linear", "symbol": "BTCUSDT", "side": "Buy", "positionIdx": 0, "orderType": "Limit", "qty": "0.001", "price": "10000", "timeInForce": "GTC"} - orderResult, err := client.NewPlaceTradeService(params).Do(context.Background()) + orderResult, err := client.NewTradeService(params).PlaceOrder(context.Background()) if err != nil { fmt.Println(err) return diff --git a/models/orderResponse.go b/models/orderResponse.go new file mode 100644 index 0000000..9c982c8 --- /dev/null +++ b/models/orderResponse.go @@ -0,0 +1,92 @@ +package models + +type OrderResult struct { + OrderId string `json:"orderId"` + OrderLinkId string `json:"orderLinkId"` +} + +type ListOrderResult struct { + List []OrderResult `json:"list"` +} + +type OrderInfo struct { + OrderId string `json:"orderId"` + OrderLinkId string `json:"orderLinkId"` + BlockTradeId string `json:"blockTradeId"` + Symbol string `json:"symbol"` + Price string `json:"price"` + Qty string `json:"qty"` + Side string `json:"side"` + IsLeverage string `json:"isLeverage"` + PositionIdx int `json:"positionIdx"` + OrderStatus string `json:"orderStatus"` + CancelType string `json:"cancelType"` + RejectReason string `json:"rejectReason"` + AvgPrice string `json:"avgPrice"` + LeavesQty string `json:"leavesQty"` + LeavesValue string `json:"leavesValue"` + CumExecQty string `json:"cumExecQty"` + CumExecValue string `json:"cumExecValue"` + CumExecFee string `json:"cumExecFee"` + TimeInForce string `json:"timeInForce"` + OrderType string `json:"orderType"` + StopOrderType string `json:"stopOrderType"` + OrderIv string `json:"orderIv"` + TriggerPrice string `json:"triggerPrice"` + TakeProfit string `json:"takeProfit"` + StopLoss string `json:"stopLoss"` + TpslMode string `json:"tpslMode"` + OcoTriggerType string `json:"ocoTriggerType"` + TpLimitPrice string `json:"tpLimitPrice"` + SlLimitPrice string `json:"slLimitPrice"` + TpTriggerBy string `json:"tpTriggerBy"` + SlTriggerBy string `json:"slTriggerBy"` + TriggerDirection int `json:"triggerDirection"` + TriggerBy string `json:"triggerBy"` + LastPriceOnCreated string `json:"lastPriceOnCreated"` + ReduceOnly bool `json:"reduceOnly"` + CloseOnTrigger bool `json:"closeOnTrigger"` + PlaceType string `json:"placeType"` + SmpType string `json:"smpType"` + SmpGroup int `json:"smpGroup"` + SmpOrderId string `json:"smpOrderId"` + CreatedTime string `json:"createdTime"` + UpdatedTime string `json:"updatedTime"` +} + +type OpenOrdersInfo struct { + Category string `json:"category"` + NextPageCursor string `json:"nextPageCursor"` + List []OrderInfo `json:"list"` +} + +type BorrowQuotaInfo struct { + Symbol string `json:"symbol"` + Side string `json:"side"` + MaxTradeQty string `json:"maxTradeQty"` + MaxTradeAmount string `json:"maxTradeAmount"` + SpotMaxTradeQty string `json:"spotMaxTradeQty"` + SpotMaxTradeAmount string `json:"spotMaxTradeAmount"` + BorrowCoin string `json:"borrowCoin"` +} + +type BatchOrderServerResponse struct { + RetCode int `json:"retCode"` + RetMsg string `json:"retMsg"` + Result struct { + List []struct { + Category string `json:"category"` + Symbol string `json:"symbol"` + OrderId string `json:"orderId"` + OrderLinkId string `json:"orderLinkId"` + CreateAt *string `json:"createAt,omitempty"` + } `json:"list"` + } `json:"result"` + RetExtInfo struct { + List []struct { + Code int `json:"code"` + Msg string `json:"msg"` + } `json:"list"` + } `json:"retExtInfo"` + Time int64 `json:"time"` +} diff --git a/models/positionResponse.go b/models/positionResponse.go new file mode 100644 index 0000000..2640e7f --- /dev/null +++ b/models/positionResponse.go @@ -0,0 +1 @@ +package models diff --git a/place_order.go b/place_order.go new file mode 100644 index 0000000..de6d503 --- /dev/null +++ b/place_order.go @@ -0,0 +1,246 @@ +package bybit_connector + +import ( + "context" + "encoding/json" + "net/http" +) + +type Order struct { + c *Client + category string + symbol string + isLeverage *int + side string + orderType string + qty string + price *string + triggerDirection *int + orderFilter *string + triggerPrice *string + triggerBy *string + orderIv *string + timeInForce *string + positionIdx *int + orderLinkId *string + takeProfit *string + stopLoss *string + tpTriggerBy *string + slTriggerBy *string + reduceOnly *bool + closeOnTrigger *bool + smpType *string + mmp *bool + tpslMode *string + tpLimitPrice *string + slLimitPrice *string + tpOrderType *string + slOrderType *string +} + +func (order *Order) TimeInForce(tif string) *Order { + order.timeInForce = &tif + return order +} + +func (order *Order) IsLeverage(isLeverage int) *Order { + order.isLeverage = &isLeverage + return order +} + +func (order *Order) TriggerPrice(triggerPrice string) *Order { + order.triggerPrice = &triggerPrice + return order +} + +func (order *Order) OrderLinkId(orderLinkId string) *Order { + order.orderLinkId = &orderLinkId + return order +} + +func (order *Order) Price(price string) *Order { + order.price = &price + return order +} + +func (order *Order) TriggerDirection(direction int) *Order { + order.triggerDirection = &direction + return order +} + +func (order *Order) OrderFilter(filter string) *Order { + order.orderFilter = &filter + return order +} + +func (order *Order) TriggerBy(triggerBy string) *Order { + order.triggerBy = &triggerBy + return order +} + +func (order *Order) OrderIv(iv string) *Order { + order.orderIv = &iv + return order +} + +func (order *Order) PositionIdx(idx int) *Order { + order.positionIdx = &idx + return order +} + +func (order *Order) TakeProfit(profit string) *Order { + order.takeProfit = &profit + return order +} + +func (order *Order) StopLoss(loss string) *Order { + order.stopLoss = &loss + return order +} + +func (order *Order) TpTriggerBy(triggerBy string) *Order { + order.tpTriggerBy = &triggerBy + return order +} + +func (order *Order) SlTriggerBy(triggerBy string) *Order { + order.slTriggerBy = &triggerBy + return order +} + +func (order *Order) ReduceOnly(reduce bool) *Order { + order.reduceOnly = &reduce + return order +} + +func (order *Order) CloseOnTrigger(close bool) *Order { + order.closeOnTrigger = &close + return order +} + +func (order *Order) SmpType(smp string) *Order { + order.smpType = &smp + return order +} + +func (order *Order) Mmp(mmp bool) *Order { + order.mmp = &mmp + return order +} + +func (order *Order) TpslMode(mode string) *Order { + order.tpslMode = &mode + return order +} + +func (order *Order) TpLimitPrice(price string) *Order { + order.tpLimitPrice = &price + return order +} + +func (order *Order) SlLimitPrice(price string) *Order { + order.slLimitPrice = &price + return order +} + +func (order *Order) TpOrderType(orderType string) *Order { + order.tpOrderType = &orderType + return order +} + +func (order *Order) SlOrderType(orderType string) *Order { + order.slOrderType = &orderType + return order +} + +func (order *Order) Do(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + r := &request{ + method: http.MethodPost, + endpoint: "/v5/order/create", + secType: secTypeSigned, + } + m := params{ + "category": order.category, + "symbol": order.symbol, + "side": order.side, + "orderType": order.orderType, + "qty": order.qty, + } + if order.price != nil { + m["price"] = *order.price + } + if order.triggerDirection != nil { + m["triggerDirection"] = *order.triggerDirection + } + if order.orderFilter != nil { + m["orderFilter"] = *order.orderFilter + } + if order.triggerPrice != nil { + m["triggerPrice"] = *order.triggerPrice + } + if order.triggerBy != nil { + m["triggerBy"] = *order.triggerBy + } + if order.orderIv != nil { + m["orderIv"] = *order.orderIv + } + if order.timeInForce != nil { + m["timeInForce"] = *order.timeInForce + } + if order.positionIdx != nil { + m["positionIdx"] = *order.positionIdx + } + if order.orderLinkId != nil { + m["orderLinkId"] = *order.orderLinkId + } + if order.takeProfit != nil { + m["takeProfit"] = *order.takeProfit + } + if order.stopLoss != nil { + m["stopLoss"] = *order.stopLoss + } + if order.tpTriggerBy != nil { + m["tpTriggerBy"] = *order.tpTriggerBy + } + if order.slTriggerBy != nil { + m["slTriggerBy"] = *order.slTriggerBy + } + if order.reduceOnly != nil { + m["reduceOnly"] = *order.reduceOnly + } + if order.closeOnTrigger != nil { + m["closeOnTrigger"] = *order.closeOnTrigger + } + if order.smpType != nil { + m["smpType"] = *order.smpType + } + if order.mmp != nil { + m["mmp"] = *order.mmp + } + if order.tpslMode != nil { + m["tpslMode"] = *order.tpslMode + } + if order.tpLimitPrice != nil { + m["tpLimitPrice"] = *order.tpLimitPrice + } + if order.slLimitPrice != nil { + m["slLimitPrice"] = *order.slLimitPrice + } + if order.tpOrderType != nil { + m["tpOrderType"] = *order.tpOrderType + } + if order.slOrderType != nil { + m["slOrderType"] = *order.slOrderType + } + r.setParams(m) + data, err := order.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} diff --git a/position.go b/position.go new file mode 100644 index 0000000..06c9e41 --- /dev/null +++ b/position.go @@ -0,0 +1 @@ +package bybit_connector diff --git a/trade.go b/trade.go index 0d89be2..f2b1535 100644 --- a/trade.go +++ b/trade.go @@ -4,259 +4,16 @@ import ( "context" "encoding/json" "github.com/wuhewuhe/bybit.go.api/handlers" + "github.com/wuhewuhe/bybit.go.api/models" "net/http" ) -type OrderResult struct { - OrderId string `json:"orderId"` - OrderLinkId string `json:"orderLinkId"` -} - type Trade struct { c *Client params map[string]interface{} } -type Order struct { - c *Client - category string - symbol string - isLeverage *int - side string - orderType string - qty string - price *string - triggerDirection *int - orderFilter *string - triggerPrice *string - triggerBy *string - orderIv *string - timeInForce *string - positionIdx *int - orderLinkId *string - takeProfit *string - stopLoss *string - tpTriggerBy *string - slTriggerBy *string - reduceOnly *bool - closeOnTrigger *bool - smpType *string - mmp *bool - tpslMode *string - tpLimitPrice *string - slLimitPrice *string - tpOrderType *string - slOrderType *string -} - -func (order *Order) TimeInForce(tif string) *Order { - order.timeInForce = &tif - return order -} - -func (order *Order) IsLeverage(isLeverage int) *Order { - order.isLeverage = &isLeverage - return order -} - -func (order *Order) TriggerPrice(triggerPrice string) *Order { - order.triggerPrice = &triggerPrice - return order -} - -func (order *Order) OrderLinkId(orderLinkId string) *Order { - order.orderLinkId = &orderLinkId - return order -} - -func (order *Order) Price(price string) *Order { - order.price = &price - return order -} - -func (order *Order) TriggerDirection(direction int) *Order { - order.triggerDirection = &direction - return order -} - -func (order *Order) OrderFilter(filter string) *Order { - order.orderFilter = &filter - return order -} - -func (order *Order) TriggerBy(triggerBy string) *Order { - order.triggerBy = &triggerBy - return order -} - -func (order *Order) OrderIv(iv string) *Order { - order.orderIv = &iv - return order -} - -func (order *Order) PositionIdx(idx int) *Order { - order.positionIdx = &idx - return order -} - -func (order *Order) TakeProfit(profit string) *Order { - order.takeProfit = &profit - return order -} - -func (order *Order) StopLoss(loss string) *Order { - order.stopLoss = &loss - return order -} - -func (order *Order) TpTriggerBy(triggerBy string) *Order { - order.tpTriggerBy = &triggerBy - return order -} - -func (order *Order) SlTriggerBy(triggerBy string) *Order { - order.slTriggerBy = &triggerBy - return order -} - -func (order *Order) ReduceOnly(reduce bool) *Order { - order.reduceOnly = &reduce - return order -} - -func (order *Order) CloseOnTrigger(close bool) *Order { - order.closeOnTrigger = &close - return order -} - -func (order *Order) SmpType(smp string) *Order { - order.smpType = &smp - return order -} - -func (order *Order) Mmp(mmp bool) *Order { - order.mmp = &mmp - return order -} - -func (order *Order) TpslMode(mode string) *Order { - order.tpslMode = &mode - return order -} - -func (order *Order) TpLimitPrice(price string) *Order { - order.tpLimitPrice = &price - return order -} - -func (order *Order) SlLimitPrice(price string) *Order { - order.slLimitPrice = &price - return order -} - -func (order *Order) TpOrderType(orderType string) *Order { - order.tpOrderType = &orderType - return order -} - -func (order *Order) SlOrderType(orderType string) *Order { - order.slOrderType = &orderType - return order -} - -func (order *Order) Do(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { - r := &request{ - method: http.MethodPost, - endpoint: "/v5/order/create", - secType: secTypeSigned, - } - m := params{ - "category": order.category, - "symbol": order.symbol, - "side": order.side, - "orderType": order.orderType, - "qty": order.qty, - } - if order.price != nil { - m["price"] = *order.price - } - if order.triggerDirection != nil { - m["triggerDirection"] = *order.triggerDirection - } - if order.orderFilter != nil { - m["orderFilter"] = *order.orderFilter - } - if order.triggerPrice != nil { - m["triggerPrice"] = *order.triggerPrice - } - if order.triggerBy != nil { - m["triggerBy"] = *order.triggerBy - } - if order.orderIv != nil { - m["orderIv"] = *order.orderIv - } - if order.timeInForce != nil { - m["timeInForce"] = *order.timeInForce - } - if order.positionIdx != nil { - m["positionIdx"] = *order.positionIdx - } - if order.orderLinkId != nil { - m["orderLinkId"] = *order.orderLinkId - } - if order.takeProfit != nil { - m["takeProfit"] = *order.takeProfit - } - if order.stopLoss != nil { - m["stopLoss"] = *order.stopLoss - } - if order.tpTriggerBy != nil { - m["tpTriggerBy"] = *order.tpTriggerBy - } - if order.slTriggerBy != nil { - m["slTriggerBy"] = *order.slTriggerBy - } - if order.reduceOnly != nil { - m["reduceOnly"] = *order.reduceOnly - } - if order.closeOnTrigger != nil { - m["closeOnTrigger"] = *order.closeOnTrigger - } - if order.smpType != nil { - m["smpType"] = *order.smpType - } - if order.mmp != nil { - m["mmp"] = *order.mmp - } - if order.tpslMode != nil { - m["tpslMode"] = *order.tpslMode - } - if order.tpLimitPrice != nil { - m["tpLimitPrice"] = *order.tpLimitPrice - } - if order.slLimitPrice != nil { - m["slLimitPrice"] = *order.slLimitPrice - } - if order.tpOrderType != nil { - m["tpOrderType"] = *order.tpOrderType - } - if order.slOrderType != nil { - m["slOrderType"] = *order.slOrderType - } - r.setParams(m) - data, err := order.c.callAPI(ctx, r, opts...) - if err != nil { - return nil, err - } - res = new(ServerResponse) - err = json.Unmarshal(data, res) - if err != nil { - return nil, err - } - return res, nil -} - -func (s *Trade) Do(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { +func (s *Trade) PlaceOrder(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { if err = handlers.ValidateParams(s.params); err != nil { return nil, err } @@ -277,3 +34,223 @@ func (s *Trade) Do(ctx context.Context, opts ...RequestOption) (res *ServerRespo } return res, nil } + +func (s *Trade) AmendOrder(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/order/amend", + secType: secTypeSigned, + } + r.setParams(s.params) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *Trade) CancelOrder(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/order/cancel", + secType: secTypeSigned, + } + r.setParams(s.params) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *Trade) GetOpenOrders(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodGet, + endpoint: "/v5/order/realtime", + secType: secTypeSigned, + } + r.setParams(s.params) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *Trade) GetOrderHistory(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodGet, + endpoint: "/v5/order/history", + secType: secTypeSigned, + } + r.setParams(s.params) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *Trade) GetSpotBorrowQuota(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodGet, + endpoint: "/v5/order/spot-borrow-check", + secType: secTypeSigned, + } + r.setParams(s.params) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *Trade) CancelAllOrders(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/order/cancel-all", + secType: secTypeSigned, + } + r.setParams(s.params) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *Trade) SetDisconnectCancelAll(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/order/disconnected-cancel-all", + secType: secTypeSigned, + } + r.setParams(s.params) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(ServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *Trade) PlaceBatchOrder(ctx context.Context, opts ...RequestOption) (res *models.BatchOrderServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/order/create-batch", + secType: secTypeSigned, + } + r.setParams(s.params) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(models.BatchOrderServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *Trade) AmendBatchOrder(ctx context.Context, opts ...RequestOption) (res *models.BatchOrderServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/order/amend-batch", + secType: secTypeSigned, + } + r.setParams(s.params) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(models.BatchOrderServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +func (s *Trade) CancelBatchOrder(ctx context.Context, opts ...RequestOption) (res *models.BatchOrderServerResponse, err error) { + if err = handlers.ValidateParams(s.params); err != nil { + return nil, err + } + r := &request{ + method: http.MethodPost, + endpoint: "/v5/order/cancel-batch", + secType: secTypeSigned, + } + r.setParams(s.params) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res = new(models.BatchOrderServerResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +}