fixedpoint: fix fixedpoint rounding

This commit is contained in:
c9s 2023-03-01 22:21:24 +08:00
parent f553ee05a0
commit 1d8df08a74
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54
4 changed files with 31 additions and 8 deletions

View File

@ -41,16 +41,18 @@ func (v Value) Trunc() Value {
func (v Value) Round(r int, mode RoundingMode) Value {
pow := math.Pow10(r)
result := v.Float64() * pow
f := v.Float64() * pow
switch mode {
case Up:
return NewFromFloat(math.Ceil(result) / pow)
f = math.Ceil(f) / pow
case HalfUp:
return NewFromFloat(math.Floor(result+0.5) / pow)
f = math.Floor(f+0.5) / pow
case Down:
return NewFromFloat(math.Floor(result) / pow)
f = math.Floor(f) / pow
}
return v
s := strconv.FormatFloat(f, 'f', r, 64)
return MustNewFromString(s)
}
func (v Value) Value() (driver.Value, error) {

View File

@ -2,10 +2,11 @@ package fixedpoint
import (
"encoding/json"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"math/big"
"testing"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
)
const Delta = 1e-9
@ -124,6 +125,12 @@ func TestRound(t *testing.T) {
assert.Equal(t, "1.23", s.Round(2, Down).String())
}
func TestNewFromString(t *testing.T) {
f, err := NewFromString("0.00000003")
assert.NoError(t, err)
assert.Equal(t, "0.00000003", f.String())
}
func TestFromString(t *testing.T) {
f := MustNewFromString("0.004075")
assert.Equal(t, "0.004075", f.String())

View File

@ -416,7 +416,7 @@ func (s *Strategy) processFilledOrder(o types.Order) {
baseSellQuantityReduction = s.aggregateOrderBaseFee(o)
s.logger.Infof("GRID BUY ORDER BASE FEE: %s %s", baseSellQuantityReduction.String(), s.Market.BaseCurrency)
baseSellQuantityReduction = baseSellQuantityReduction.Round(s.Market.VolumePrecision, fixedpoint.Up)
baseSellQuantityReduction = roundUpMarketQuantity(s.Market, baseSellQuantityReduction)
s.logger.Infof("GRID BUY ORDER BASE FEE (Rounding with precision %d): %s %s",
s.Market.VolumePrecision,
baseSellQuantityReduction.String(),
@ -1766,3 +1766,7 @@ func (s *Strategy) openOrdersMismatches(ctx context.Context, session *bbgo.Excha
return false, nil
}
func roundUpMarketQuantity(market types.Market, v fixedpoint.Value) fixedpoint.Value {
return v.Round(market.VolumePrecision, fixedpoint.Up)
}

View File

@ -917,3 +917,13 @@ func TestStrategy_checkMinimalQuoteInvestment(t *testing.T) {
assert.EqualError(t, err, "need at least 14979.995500 USDT for quote investment, 10000.000000 USDT given")
})
}
func Test_roundUpMarketQuantity(t *testing.T) {
q := number("0.00000003")
assert.Equal(t, "0.00000003", q.String())
q3 := roundUpMarketQuantity(types.Market{
VolumePrecision: 8,
}, q)
assert.Equal(t, "0.00000003", q3.String(), "rounding prec 8")
}