Skip to content

Commit

Permalink
Merge branch 'adshao:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
ntminh611 authored Mar 1, 2024
2 parents 7c76682 + 52be7e1 commit 090f348
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 11 deletions.
5 changes: 5 additions & 0 deletions v2/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1022,3 +1022,8 @@ func (c *Client) NewSubAccountFuturesAccountService() *SubAccountFuturesAccountS
func (c *Client) NewSubAccountFuturesSummaryV1Service() *SubAccountFuturesSummaryV1Service {
return &SubAccountFuturesSummaryV1Service{c: c}
}

// NewSubAccountFuturesTransferV1Service Futures Transfer for Sub-account (For Master Account)
func (c *Client) NewSubAccountFuturesTransferV1Service() *SubAccountFuturesTransferV1Service {
return &SubAccountFuturesTransferV1Service{c: c}
}
41 changes: 31 additions & 10 deletions v2/futures/order_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"fmt"
"net/http"
"strings"

"github.com/adshao/go-binance/v2/common"
)

// CreateOrderService create order
Expand Down Expand Up @@ -802,8 +804,23 @@ type CreateBatchOrdersService struct {
orders []*CreateOrderService
}

// CreateBatchOrdersResponse contains the response from CreateBatchOrders operation
type CreateBatchOrdersResponse struct {
// Total number of messages in the response
N int
// List of orders which were placed successfully which can have a length between 0 and N
Orders []*Order
// List of errors of length N, where each item corresponds to a nil value if
// the order from that specific index was placed succeessfully OR an non-nil *APIError if there was an error with
// the order at that index
Errors []error
}

func newCreateBatchOrdersResponse(n int) *CreateBatchOrdersResponse {
return &CreateBatchOrdersResponse{
N: n,
Errors: make([]error, n),
}
}

func (s *CreateBatchOrdersService) OrderList(orders []*CreateOrderService) *CreateBatchOrdersService {
Expand Down Expand Up @@ -882,26 +899,30 @@ func (s *CreateBatchOrdersService) Do(ctx context.Context, opts ...RequestOption
rawMessages := make([]*json.RawMessage, 0)

err = json.Unmarshal(data, &rawMessages)

if err != nil {
return &CreateBatchOrdersResponse{}, err
}

batchCreateOrdersResponse := new(CreateBatchOrdersResponse)

for _, j := range rawMessages {
o := new(Order)
if err := json.Unmarshal(*j, o); err != nil {
return &CreateBatchOrdersResponse{}, err
batchCreateOrdersResponse := newCreateBatchOrdersResponse(len(rawMessages))
for i, j := range rawMessages {
// check if response is an API error
e := new(common.APIError)
if err := json.Unmarshal(*j, e); err != nil {
return nil, err
}

if o.ClientOrderID != "" {
batchCreateOrdersResponse.Orders = append(batchCreateOrdersResponse.Orders, o)
if e.Code > 0 || e.Message != "" {
batchCreateOrdersResponse.Errors[i] = e
continue
}

o := new(Order)
if err := json.Unmarshal(*j, o); err != nil {
return nil, err
}

batchCreateOrdersResponse.Orders = append(batchCreateOrdersResponse.Orders, o)
}

return batchCreateOrdersResponse, nil

}
92 changes: 92 additions & 0 deletions v2/futures/order_service_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package futures

import (
"context"
"testing"

"github.com/adshao/go-binance/v2/common"
"github.com/stretchr/testify/suite"
)

Expand Down Expand Up @@ -613,3 +615,93 @@ func (s *orderServiceTestSuite) assertLiquidationEqual(e, a *LiquidationOrder) {
r.Equal(e.Type, a.Type, "Type")
r.Equal(e.Side, a.Side, "Side")
}

func (s *orderServiceTestSuite) TestCreateBatchOrders() {
data := []byte(`[
{
"code": -2014,
"msg": "API-key format invalid."
},
{
"clientOrderId": "testOrder",
"cumQty": "0",
"cumQuote": "0",
"executedQty": "0",
"orderId": 22542179,
"avgPrice": "0.00000",
"origQty": "10",
"price": "100",
"reduceOnly": false,
"side": "BUY",
"positionSide": "SHORT",
"status": "NEW",
"stopPrice": "9300",
"symbol": "BTCUSDT",
"timeInForce": "GTC",
"type": "TRAILING_STOP_MARKET",
"origType": "TRAILING_STOP_MARKET",
"activatePrice": "9020",
"priceRate": "0.3",
"updateTime": 1566818724722,
"workingType": "CONTRACT_PRICE",
"priceProtect": false,
"priceMatch": "NONE",
"selfTradePreventionMode": "NONE",
"goodTillDate": 0
},
{
"code": -2022,
"msg": "ReduceOnly Order is rejected."
}
]`)
s.mockDo(data, nil)
defer s.assertDo()

res, err := s.client.NewCreateBatchOrdersService().OrderList([]*CreateOrderService{{}, {}, {}}).Do(context.Background())
r := s.r()
r.NoError(err)

e := &CreateBatchOrdersResponse{
N: 3,
Orders: []*Order{
{
Symbol: "BTCUSDT",
OrderID: 22542179,
ClientOrderID: "testOrder",
Price: "100",
ReduceOnly: false,
OrigQuantity: "10",
ExecutedQuantity: "0",
CumQuantity: "0",
CumQuote: "0",
Status: "NEW",
TimeInForce: "GTC",
Type: "TRAILING_STOP_MARKET",
Side: "BUY",
StopPrice: "9300",
Time: 0,
UpdateTime: 1566818724722,
WorkingType: "CONTRACT_PRICE",
ActivatePrice: "9020",
PriceRate: "0.3",
AvgPrice: "0.00000",
OrigType: "TRAILING_STOP_MARKET",
PositionSide: "SHORT",
PriceProtect: false,
ClosePosition: false,
},
},
Errors: []error{
&common.APIError{
Code: -2014,
Message: "API-key format invalid.",
},
nil,
&common.APIError{
Code: -2022,
Message: "ReduceOnly Order is rejected.",
},
},
}
r.EqualValues(e, res)
}
2 changes: 1 addition & 1 deletion v2/futures/ticker_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (s *ListPricesService) Symbol(symbol string) *ListPricesService {
func (s *ListPricesService) Do(ctx context.Context, opts ...RequestOption) (res []*SymbolPrice, err error) {
r := &request{
method: http.MethodGet,
endpoint: "/fapi/v1/ticker/price",
endpoint: "/fapi/v2/ticker/price",
}
if s.symbol != nil {
r.setParam("symbol", *s.symbol)
Expand Down
67 changes: 67 additions & 0 deletions v2/subaccount_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package binance

import (
"context"
"net/http"
)

// TransferToSubAccountService transfer to subaccount
Expand Down Expand Up @@ -607,3 +608,69 @@ type SubAccountFuturesSummaryV1SubAccountList struct {
Email string `json:"email"`
SubAccountFuturesSummaryCommon
}

// SubAccountFuturesTransferV1Service Futures Transfer for Sub-account (For Master Account)
// https://binance-docs.github.io/apidocs/spot/en/#futures-transfer-for-sub-account-for-master-account
type SubAccountFuturesTransferV1Service struct {
c *Client
email string
asset string
amount float64
/*
1: transfer from subaccount's spot account to its USDT-margined futures account
2: transfer from subaccount's USDT-margined futures account to its spot account
3: transfer from subaccount's spot account to its COIN-margined futures account
4:transfer from subaccount's COIN-margined futures account to its spot account
*/
transferType int
}

func (s *SubAccountFuturesTransferV1Service) Email(v string) *SubAccountFuturesTransferV1Service {
s.email = v
return s
}

func (s *SubAccountFuturesTransferV1Service) Asset(v string) *SubAccountFuturesTransferV1Service {
s.asset = v
return s
}

func (s *SubAccountFuturesTransferV1Service) Amount(v float64) *SubAccountFuturesTransferV1Service {
s.amount = v
return s
}

func (s *SubAccountFuturesTransferV1Service) TransferType(v int) *SubAccountFuturesTransferV1Service {
s.transferType = v
return s
}

func (s *SubAccountFuturesTransferV1Service) Do(ctx context.Context, opts ...RequestOption) (res *SubAccountFuturesTransferResponse, err error) {
r := &request{
method: http.MethodPost,
endpoint: "/sapi/v1/sub-account/futures/transfer",
secType: secTypeSigned,
}
m := params{
"email": s.email,
"asset": s.asset,
"amount": s.amount,
"type": s.transferType,
}
r.setParams(m)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(SubAccountFuturesTransferResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}

type SubAccountFuturesTransferResponse struct {
// seems api doc bug, return `tranId` as int64 actually in production environment
TranID int64 `json:"tranId"`
}
32 changes: 32 additions & 0 deletions v2/subaccount_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,3 +301,35 @@ func (s *subAccountServiceTestSuite) assertAccountFuturesAssetsEqual(e, a *SubAc
r.Equal(e.UnrealizedProfit, a.UnrealizedProfit, "UnrealizedProfit")
r.Equal(e.WalletBalance, a.WalletBalance, "WalletBalance")
}

func (s *subAccountServiceTestSuite) TestSubAccountFuturesTransferService() {
data := []byte(`
{
"tranId": 123456789
}
`)
s.mockDo(data, nil)
defer s.assertDo()

email := "[email protected]"
asset := "USDT"
amount := 1.0
tType := 1
s.assertReq(func(r *request) {
e := newSignedRequest().
setParams(params{
"email": email,
"asset": asset,
"amount": amount,
"type": tType,
})
s.assertRequestEqual(e, r)
})

response, err := s.client.NewSubAccountFuturesTransferV1Service().Email(email).Asset(asset).Amount(amount).TransferType(tType).Do(newContext())

r := s.r()
r.NoError(err)
r.Equal(int64(123456789), response.TranID, "TranID")

}

0 comments on commit 090f348

Please sign in to comment.