schedule: add MinBaseBalance config

This commit is contained in:
c9s 2023-06-07 16:36:38 +08:00
parent e0e27e75bb
commit 0f141c7f79
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54

View File

@ -38,6 +38,7 @@ type Strategy struct {
bbgo.QuantityOrAmount bbgo.QuantityOrAmount
MinBaseBalance fixedpoint.Value `json:"minBaseBalance"`
MaxBaseBalance fixedpoint.Value `json:"maxBaseBalance"` MaxBaseBalance fixedpoint.Value `json:"maxBaseBalance"`
BelowMovingAverage *bbgo.MovingAverageSettings `json:"belowMovingAverage,omitempty"` BelowMovingAverage *bbgo.MovingAverageSettings `json:"belowMovingAverage,omitempty"`
@ -163,38 +164,52 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
// calculate quote quantity for balance checking // calculate quote quantity for balance checking
quoteQuantity := quantity.Mul(closePrice) quoteQuantity := quantity.Mul(closePrice)
// execute orders
switch side {
case types.SideTypeBuy:
if !s.MaxBaseBalance.IsZero() {
if baseBalance, ok := session.GetAccount().Balance(s.Market.BaseCurrency); ok {
total := baseBalance.Total()
if total.Add(quantity).Compare(s.MaxBaseBalance) >= 0 {
quantity = s.MaxBaseBalance.Sub(total)
quoteQuantity = quantity.Mul(closePrice)
}
}
}
quoteBalance, ok := session.GetAccount().Balance(s.Market.QuoteCurrency) quoteBalance, ok := session.GetAccount().Balance(s.Market.QuoteCurrency)
if !ok { if !ok {
log.Errorf("can not place scheduled %s order, quote balance %s is empty", s.Symbol, s.Market.QuoteCurrency) log.Errorf("can not place scheduled %s order, quote balance %s is empty", s.Symbol, s.Market.QuoteCurrency)
return return
} }
baseBalance, ok := session.GetAccount().Balance(s.Market.BaseCurrency)
if !ok {
log.Errorf("can not place scheduled %s order, base balance %s is empty", s.Symbol, s.Market.BaseCurrency)
return
}
totalBase := baseBalance.Total()
// execute orders
switch side {
case types.SideTypeBuy:
if !s.MaxBaseBalance.IsZero() {
if totalBase.Add(quantity).Compare(s.MaxBaseBalance) >= 0 {
quantity = s.MaxBaseBalance.Sub(totalBase)
quoteQuantity = quantity.Mul(closePrice)
}
}
// if min base balance is defined
if !s.MinBaseBalance.IsZero() && s.MinBaseBalance.Compare(totalBase) > 0 {
quantity = fixedpoint.Max(quantity, s.MinBaseBalance.Sub(totalBase))
quantity = fixedpoint.Max(quantity, s.Market.MinQuantity)
}
if quoteBalance.Available.Compare(quoteQuantity) < 0 { if quoteBalance.Available.Compare(quoteQuantity) < 0 {
log.Errorf("can not place scheduled %s order: quote balance %s is not enough: %v < %v", s.Symbol, s.Market.QuoteCurrency, quoteBalance.Available, quoteQuantity) log.Errorf("can not place scheduled %s order: quote balance %s is not enough: %v < %v", s.Symbol, s.Market.QuoteCurrency, quoteBalance.Available, quoteQuantity)
return return
} }
case types.SideTypeSell: case types.SideTypeSell:
baseBalance, ok := session.GetAccount().Balance(s.Market.BaseCurrency) quantity = fixedpoint.Min(quantity, baseBalance.Available)
if !ok {
log.Errorf("can not place scheduled %s order, base balance %s is empty", s.Symbol, s.Market.BaseCurrency) // skip sell if we hit the minBaseBalance line
if !s.MinBaseBalance.IsZero() {
if totalBase.Sub(quantity).Compare(s.MinBaseBalance) < 0 {
return return
} }
}
quantity = fixedpoint.Min(quantity, baseBalance.Available)
quoteQuantity = quantity.Mul(closePrice) quoteQuantity = quantity.Mul(closePrice)
} }