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 { func (v Value) Round(r int, mode RoundingMode) Value {
pow := math.Pow10(r) pow := math.Pow10(r)
result := v.Float64() * pow f := v.Float64() * pow
switch mode { switch mode {
case Up: case Up:
return NewFromFloat(math.Ceil(result) / pow) f = math.Ceil(f) / pow
case HalfUp: case HalfUp:
return NewFromFloat(math.Floor(result+0.5) / pow) f = math.Floor(f+0.5) / pow
case Down: 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) { func (v Value) Value() (driver.Value, error) {

View File

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

View File

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