mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-25 16:25:16 +00:00
types: fix AdjustQuantityByMinNotional by round up the quantity
This commit is contained in:
parent
c3ca5b75ac
commit
02c28a07cc
|
@ -2,6 +2,7 @@ package types
|
|||
|
||||
import (
|
||||
"math"
|
||||
"strconv"
|
||||
|
||||
"github.com/leekchan/accounting"
|
||||
|
||||
|
@ -59,7 +60,14 @@ func (m Market) IsDustQuantity(quantity, price fixedpoint.Value) bool {
|
|||
|
||||
// TruncateQuantity uses the step size to truncate floating number, in order to avoid the rounding issue
|
||||
func (m Market) TruncateQuantity(quantity fixedpoint.Value) fixedpoint.Value {
|
||||
return fixedpoint.MustNewFromString(m.FormatQuantity(quantity))
|
||||
var ts = m.StepSize.Float64()
|
||||
var prec = int(math.Round(math.Log10(ts) * -1.0))
|
||||
var pow10 = math.Pow10(prec)
|
||||
|
||||
qf := math.Trunc(quantity.Float64() * pow10)
|
||||
qf = qf / pow10
|
||||
qs := strconv.FormatFloat(qf, 'f', prec, 64)
|
||||
return fixedpoint.MustNewFromString(qs)
|
||||
}
|
||||
|
||||
func (m Market) TruncatePrice(price fixedpoint.Value) fixedpoint.Value {
|
||||
|
@ -136,15 +144,18 @@ func (m Market) CanonicalizeVolume(val fixedpoint.Value) float64 {
|
|||
return math.Trunc(p*val.Float64()) / p
|
||||
}
|
||||
|
||||
var minNotionalSealant = fixedpoint.NewFromFloat(1.0001)
|
||||
|
||||
// AdjustQuantityByMinNotional adjusts the quantity to make the amount greater than the given minAmount
|
||||
func (m Market) AdjustQuantityByMinNotional(quantity, currentPrice fixedpoint.Value) fixedpoint.Value {
|
||||
// modify quantity for the min amount
|
||||
quantity = m.TruncateQuantity(quantity)
|
||||
amount := currentPrice.Mul(quantity)
|
||||
if amount.Compare(m.MinNotional) < 0 {
|
||||
ratio := m.MinNotional.Mul(minNotionalSealant).Div(amount)
|
||||
return quantity.Mul(ratio)
|
||||
ratio := m.MinNotional.Div(amount)
|
||||
quantity = quantity.Mul(ratio)
|
||||
|
||||
ts := m.StepSize.Float64()
|
||||
prec := int(math.Round(math.Log10(ts) * -1.0))
|
||||
return quantity.Round(prec, fixedpoint.Up)
|
||||
}
|
||||
|
||||
return quantity
|
||||
|
|
|
@ -191,3 +191,53 @@ func Test_formatQuantity(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarket_TruncateQuantity(t *testing.T) {
|
||||
market := Market{
|
||||
StepSize: fixedpoint.NewFromFloat(0.0001),
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
input string
|
||||
expect string
|
||||
}{
|
||||
{"0.00573961", "0.0057"},
|
||||
{"0.00579961", "0.0057"},
|
||||
{"0.0057", "0.0057"},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
q := fixedpoint.MustNewFromString(testCase.input)
|
||||
q2 := market.TruncateQuantity(q)
|
||||
assert.Equalf(t, testCase.expect, q2.String(), "input: %s stepSize: %s", testCase.input, market.StepSize.String())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestMarket_AdjustQuantityByMinNotional(t *testing.T) {
|
||||
|
||||
market := Market{
|
||||
Symbol: "ETHUSDT",
|
||||
StepSize: fixedpoint.NewFromFloat(0.0001),
|
||||
MinQuantity: fixedpoint.NewFromFloat(0.0001),
|
||||
MinNotional: fixedpoint.NewFromFloat(10.0),
|
||||
VolumePrecision: 8,
|
||||
PricePrecision: 2,
|
||||
}
|
||||
|
||||
// Quantity:0.00573961 Price:1750.99
|
||||
testCases := []struct {
|
||||
input string
|
||||
expect string
|
||||
}{
|
||||
{"0.00573961", "0.0058"},
|
||||
}
|
||||
|
||||
price := fixedpoint.NewFromFloat(1750.99)
|
||||
for _, testCase := range testCases {
|
||||
q := fixedpoint.MustNewFromString(testCase.input)
|
||||
q2 := market.AdjustQuantityByMinNotional(q, price)
|
||||
assert.Equalf(t, testCase.expect, q2.String(), "input: %s stepSize: %s", testCase.input, market.StepSize.String())
|
||||
assert.False(t, market.IsDustQuantity(q2, price))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user