diff --git a/v2/common/helpers.go b/v2/common/helpers.go index 5a5df703..7fa98979 100644 --- a/v2/common/helpers.go +++ b/v2/common/helpers.go @@ -3,12 +3,21 @@ package common import ( "bytes" "fmt" - "math" + + "github.com/shopspring/decimal" ) -// AmountToLotSize converts an amount to a lot sized amount -func AmountToLotSize(lot float64, precision int, amount float64) float64 { - return math.Trunc(math.Floor(amount/lot)*lot*math.Pow10(precision)) / math.Pow10(precision) +// AmountToLotSize convert amount to lot size +func AmountToLotSize(amount, minQty, stepSize string, precision int) string { + amountDec := decimal.RequireFromString(amount) + minQtyDec := decimal.RequireFromString(minQty) + baseAmountDec := amountDec.Sub(minQtyDec) + if baseAmountDec.LessThan(decimal.RequireFromString("0")) { + return "0" + } + stepSizeDec := decimal.RequireFromString(stepSize) + baseAmountDec = baseAmountDec.Div(stepSizeDec).Truncate(0).Mul(stepSizeDec) + return baseAmountDec.Add(minQtyDec).Truncate(int32(precision)).String() } // ToJSONList convert v to json list if v is a map diff --git a/v2/common/helpers_test.go b/v2/common/helpers_test.go index c57af54f..1121a4f5 100644 --- a/v2/common/helpers_test.go +++ b/v2/common/helpers_test.go @@ -9,55 +9,101 @@ import ( func TestAmountToLotSize(t *testing.T) { assert := assert.New(t) type args struct { - lot float64 + minQty string + stepSize string + amount string precision int - amount float64 } tests := []struct { - name string - args args - want float64 + name string + args args + expect string }{ { name: "test with lot of zero and invalid amount", args: args{ - lot: 0.00100000, + minQty: "0.01", + stepSize: "0.01", + amount: "0.001", precision: 8, - amount: 0.00010000, }, - want: 0, + expect: "0", }, { name: "test with lot", args: args{ - lot: 0.00100000, - precision: 3, - amount: 1.39, + minQty: "0.01", + stepSize: "0.01", + amount: "1.39", + precision: 8, + }, + expect: "1.39", + }, + { + name: "test with exact precision", + args: args{ + minQty: "0.01", + stepSize: "0.01", + amount: "1.39", + precision: 2, + }, + expect: "1.39", + }, + { + name: "test with small precision", + args: args{ + minQty: "0.01", + stepSize: "0.01", + amount: "1.39", + precision: 1, }, - want: 1.389, + expect: "1.3", + }, + { + name: "test with zero precision", + args: args{ + minQty: "0.01", + stepSize: "0.01", + amount: "1.39", + precision: 0, + }, + expect: "1", }, { name: "test with big decimal", args: args{ - lot: 0.00100000, + minQty: "0.01", + stepSize: "0.02", + amount: "11.31232419283240912834434", precision: 8, - amount: 11.31232419283240912834434, }, - want: 11.312, + expect: "11.31", }, { name: "test with big number", args: args{ - lot: 0.0010000, + minQty: "0.0001", + stepSize: "0.02", + amount: "11232821093480213.31232419283240912834434", precision: 8, - amount: 11232821093480213.31232419283240912834434, }, - want: 11232821093480213.3123, + expect: "11232821093480213.3001", + }, + { + name: "test with small decimal", + args: args{ + minQty: "0.0000010", + stepSize: "0.0000010", + amount: "0.003923153000000002", + precision: 7, + }, + expect: "0.003923", }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - assert.Equal(tt.want, AmountToLotSize(tt.args.lot, tt.args.precision, tt.args.amount)) + assert.Equal(tt.expect, AmountToLotSize(tt.args.amount, tt.args.minQty, tt.args.stepSize, tt.args.precision)) }) } } diff --git a/v2/go.mod b/v2/go.mod index 01887616..49d908ea 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -8,6 +8,7 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.0 github.com/jpillora/backoff v1.0.0 + github.com/shopspring/decimal v1.4.0 github.com/stretchr/testify v1.8.1 ) diff --git a/v2/go.sum b/v2/go.sum index a1db0a15..d7cb74bf 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -20,6 +20,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=