diff --git a/.github/workflows/connector.yml b/.github/workflows/connector.yml index ff2730d..f580405 100644 --- a/.github/workflows/connector.yml +++ b/.github/workflows/connector.yml @@ -4,14 +4,18 @@ on: push: branches: - master + - main pull_request: branches: - master + - main - rc-** jobs: Checks: runs-on: ubuntu-latest + env: + GO111MODULE: on steps: - uses: actions/checkout@v3 - name: Setup Go diff --git a/CHANGELOG.md b/CHANGELOG.md index 58c3ca1..c233a23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change log +## v0.5.1 - 2023-08-21 + +### Fixed +- Implemented a fix for the automatic conversion to scientific notation when handling large `quantity` values. + ## v0.5.0 - 2023-06-30 ### Added diff --git a/account.go b/account.go index 3c1f4aa..7ffecb5 100644 --- a/account.go +++ b/account.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "net/http" + "strconv" ) // Binance Test New Order endpoint (POST /api/v3/order/test) @@ -130,7 +131,7 @@ func (s *TestNewOrder) Do(ctx context.Context, opts ...RequestOption) (res *Acco r.setParam("timeInForce", *s.timeInForce) } if s.quantity != nil { - r.setParam("quantity", *s.quantity) + r.setParam("quantity", strconv.FormatFloat(*s.quantity, 'f', -1, 64)) } if s.quoteOrderQty != nil { r.setParam("quoteOrderQty", *s.quoteOrderQty) @@ -316,7 +317,7 @@ func (s *CreateOrderService) Do(ctx context.Context, opts ...RequestOption) (res r.setParam("timeInForce", *s.timeInForce) } if s.quantity != nil { - r.setParam("quantity", *s.quantity) + r.setParam("quantity", strconv.FormatFloat(*s.quantity, 'f', -1, 64)) } if s.quoteOrderQty != nil { r.setParam("quoteOrderQty", *s.quoteOrderQty) @@ -833,7 +834,7 @@ func (s *CancelReplaceService) Do(ctx context.Context, opts ...RequestOption) (r m["timeInForce"] = *s.timeInForce } if s.quantity != nil { - m["quantity"] = *s.quantity + m["quantity"] = strconv.FormatFloat(*s.quantity, 'f', -1, 64) } if s.quoteOrderQty != nil { m["quoteOrderQty"] = *s.quoteOrderQty @@ -1293,7 +1294,7 @@ func (s *NewOCOService) Do(ctx context.Context, opts ...RequestOption) (res *Ord m := params{ "symbol": s.symbol, "side": s.side, - "quantity": s.quantity, + "quantity": strconv.FormatFloat(s.quantity, 'f', -1, 64), "price": s.price, "stopPrice": s.stopPrice, } diff --git a/account_test.go b/account_test.go index 0df42f1..0b66e12 100644 --- a/account_test.go +++ b/account_test.go @@ -2,6 +2,7 @@ package binance_connector import ( "context" + "strconv" "testing" "github.com/stretchr/testify/suite" @@ -176,42 +177,95 @@ func (s *baseTestSuite) assertMyTradesEqual(e, a *AccountTradeListResponse) { func (s *accountTestSuite) TestNewOrder() { data := []byte(`{ "symbol": "BTCUSDT", - "orderId": 28 + "orderId": 28, + "orderListId": -1, + "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP", + "transactTime": 1507725176595, + "price": "0.00000000", + "origQty": "10.00000000", + "executedQty": "10.00000000", + "cummulativeQuoteQty": "10.00000000", + "status": "FILLED", + "timeInForce": "GTC", + "type": "MARKET", + "side": "SELL", + "workingTime": 1507725176595, + "selfTradePreventionMode": "NONE" }`) s.mockDo(data, nil) defer s.assertDo() + symbol := "BTCUSDT" + side := "SELL" + orderType := "MARKET" + quantity := 10.0 + clientOrderId := "6gCrw2kRUAF9CvJDGP16IP" + respType := "RESULT" + s.assertReq(func(r *request) { - e := newSignedRequest() - e.setParam("symbol", "BTCUSDT") - e.setParam("side", "BUY") - e.setParam("type", "LIMIT") - e.setParam("quantity", 1) - e.setParam("price", 100) + e := newSignedRequest().setParams(params{ + "symbol": symbol, + "side": side, + "type": orderType, + "quantity": quantity, + "newClientOrderId": clientOrderId, + "newOrderRespType": respType, + }) s.assertRequestEqual(e, r) + inputQuantity := strconv.FormatFloat(quantity, 'f', -1, 64) // Convert the quantity from float to string + apiQuantity := r.query.Get("quantity") + s.Equal(inputQuantity, apiQuantity, "User-input quantity does not match API value") // Check value of quantity being sent is same as input }) - ctx := context.Background() - res, err := s.client.NewCreateOrderService(). - Symbol("BTCUSDT"). - Side("BUY"). - Type("LIMIT"). - Quantity(1). - Price(100). - Do(ctx) + orderResp, err := s.client.NewCreateOrderService().Symbol(symbol). + Side(side).Type(orderType). + Quantity(quantity). + NewClientOrderId(clientOrderId). + NewOrderRespType(respType). + Do(newContext()) - s.r().NoError(err) - e := &CreateOrderResponseFULL{ - Symbol: "BTCUSDT", - OrderId: 28, + r := s.r() + r.NoError(err) + r.NotNil(orderResp) + + expectedResp := &CreateOrderResponseRESULT{ + Symbol: "BTCUSDT", + OrderId: 28, + OrderListId: -1, + ClientOrderId: "6gCrw2kRUAF9CvJDGP16IP", + TransactTime: 1507725176595, + Price: "0.00000000", + OrigQty: "10.00000000", + ExecutedQty: "10.00000000", + CumulativeQuoteQty: "10.00000000", + Status: "FILLED", + TimeInForce: "GTC", + Type: "MARKET", + Side: "SELL", + WorkingTime: 1507725176595, + SelfTradePreventionMode: "NONE", } - s.assertCreateOrderResponseEqual(e, res.(*CreateOrderResponseFULL)) + + s.assertCreateOrderResponseEqual(expectedResp, orderResp.(*CreateOrderResponseRESULT)) } -func (s *accountTestSuite) assertCreateOrderResponseEqual(e, a *CreateOrderResponseFULL) { +func (s *baseTestSuite) assertCreateOrderResponseEqual(e, a *CreateOrderResponseRESULT) { r := s.r() r.Equal(e.Symbol, a.Symbol, "Symbol") r.Equal(e.OrderId, a.OrderId, "OrderId") + r.Equal(e.OrderListId, a.OrderListId, "OrderListId") + r.Equal(e.ClientOrderId, a.ClientOrderId, "ClientOrderId") + r.Equal(e.TransactTime, a.TransactTime, "TransactTime") + r.Equal(e.Price, a.Price, "Price") + r.Equal(e.OrigQty, a.OrigQty, "OrigQty") + r.Equal(e.ExecutedQty, a.ExecutedQty, "ExecutedQty") + r.Equal(e.CumulativeQuoteQty, a.CumulativeQuoteQty, "CumulativeQuoteQty") + r.Equal(e.Status, a.Status, "Status") + r.Equal(e.TimeInForce, a.TimeInForce, "TimeInForce") + r.Equal(e.Type, a.Type, "Type") + r.Equal(e.Side, a.Side, "Side") + r.Equal(e.WorkingTime, a.WorkingTime, "WorkingTime") + r.Equal(e.SelfTradePreventionMode, a.SelfTradePreventionMode, "SelfTradePreventionMode") } func (s *accountTestSuite) TestCancelOrder() { diff --git a/consts.go b/consts.go index baae2eb..040c9f8 100644 --- a/consts.go +++ b/consts.go @@ -2,4 +2,4 @@ package binance_connector const Name = "binance-connector-go" -const Version = "0.5.0" +const Version = "0.5.1" diff --git a/go.mod b/go.mod index e5ce9da..10ba1ae 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/bitly/go-simplejson v0.5.0 github.com/gorilla/websocket v1.5.0 - github.com/stretchr/testify v1.8.2 + github.com/stretchr/testify v1.8.4 ) require ( diff --git a/go.sum b/go.sum index 4bb3ae8..6d2d955 100644 --- a/go.sum +++ b/go.sum @@ -25,6 +25,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=