xmaker: truncate quantity when hedging

This commit is contained in:
c9s 2021-12-26 15:44:41 +08:00
parent 05a0745d08
commit 902e27ede4
2 changed files with 15 additions and 6 deletions

View File

@ -501,6 +501,7 @@ func (s *Strategy) Hedge(ctx context.Context, pos fixedpoint.Value) {
} }
quantity := fixedpoint.Abs(pos) quantity := fixedpoint.Abs(pos)
quantity = s.sourceMarket.TruncateQuantity(quantity)
if pos < 0 { if pos < 0 {
side = types.SideTypeSell side = types.SideTypeSell

View File

@ -8,6 +8,8 @@ import (
"time" "time"
"github.com/leekchan/accounting" "github.com/leekchan/accounting"
"github.com/c9s/bbgo/pkg/fixedpoint"
) )
type Duration time.Duration type Duration time.Duration
@ -49,7 +51,7 @@ func (d *Duration) UnmarshalJSON(data []byte) error {
} }
type Market struct { type Market struct {
Symbol string `json:"symbol"` Symbol string `json:"symbol"`
// LocalSymbol is used for exchange's API (exchange package internal) // LocalSymbol is used for exchange's API (exchange package internal)
LocalSymbol string `json:"localSymbol,omitempty"` LocalSymbol string `json:"localSymbol,omitempty"`
@ -57,7 +59,7 @@ type Market struct {
// PricePrecision is the precision used for formatting price, 8 = 8 decimals // PricePrecision is the precision used for formatting price, 8 = 8 decimals
// can be converted from price tick step size, e.g. // can be converted from price tick step size, e.g.
// int(math.Log10(price step size)) // int(math.Log10(price step size))
PricePrecision int `json:"pricePrecision"` PricePrecision int `json:"pricePrecision"`
// VolumePrecision is the precision used for formatting quantity and volume, 8 = 8 decimals // VolumePrecision is the precision used for formatting quantity and volume, 8 = 8 decimals
// can be converted from step size, e.g. // can be converted from step size, e.g.
@ -65,10 +67,10 @@ type Market struct {
VolumePrecision int `json:"volumePrecision"` VolumePrecision int `json:"volumePrecision"`
// QuoteCurrency is the currency name for quote, e.g. USDT in BTC/USDT, USDC in BTC/USDC // QuoteCurrency is the currency name for quote, e.g. USDT in BTC/USDT, USDC in BTC/USDC
QuoteCurrency string `json:"quoteCurrency"` QuoteCurrency string `json:"quoteCurrency"`
// BaseCurrency is the current name for base, e.g. BTC in BTC/USDT, ETH in ETH/USDC // BaseCurrency is the current name for base, e.g. BTC in BTC/USDT, ETH in ETH/USDC
BaseCurrency string `json:"baseCurrency"` BaseCurrency string `json:"baseCurrency"`
// The MIN_NOTIONAL filter defines the minimum notional value allowed for an order on a symbol. // The MIN_NOTIONAL filter defines the minimum notional value allowed for an order on a symbol.
// An order's notional value is the price * quantity // An order's notional value is the price * quantity
@ -84,7 +86,7 @@ type Market struct {
// StepSize is the step size of quantity // StepSize is the step size of quantity
// can be converted from precision, e.g. // can be converted from precision, e.g.
// 1.0 / math.Pow10(m.BaseUnitPrecision) // 1.0 / math.Pow10(m.BaseUnitPrecision)
StepSize float64 `json:"stepSize,omitempty"` StepSize float64 `json:"stepSize,omitempty"`
MinPrice float64 `json:"minPrice,omitempty"` MinPrice float64 `json:"minPrice,omitempty"`
MaxPrice float64 `json:"maxPrice,omitempty"` MaxPrice float64 `json:"maxPrice,omitempty"`
@ -93,6 +95,12 @@ type Market struct {
TickSize float64 `json:"tickSize,omitempty"` TickSize float64 `json:"tickSize,omitempty"`
} }
// 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 {
stepRound := math.Pow10(-int(math.Log10(m.StepSize)))
return fixedpoint.NewFromFloat(math.Trunc(quantity.Float64()*stepRound) / stepRound)
}
func (m Market) BaseCurrencyFormatter() *accounting.Accounting { func (m Market) BaseCurrencyFormatter() *accounting.Accounting {
a := accounting.DefaultAccounting(m.BaseCurrency, m.VolumePrecision) a := accounting.DefaultAccounting(m.BaseCurrency, m.VolumePrecision)
a.Format = "%v %s" a.Format = "%v %s"