grid2: fix TestStrategy_checkRequiredInvestmentByQuantity

This commit is contained in:
c9s 2022-11-16 12:09:55 +08:00
parent d0bdc859fb
commit dcbce8aa5c
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54
2 changed files with 35 additions and 17 deletions

View File

@ -183,19 +183,22 @@ type InvestmentBudget struct {
quoteBalance fixedpoint.Value
}
func (s *Strategy) checkRequiredInvestmentByQuantity(baseInvestment, quoteInvestment, baseBalance, quoteBalance, quantity, lastPrice fixedpoint.Value, pins []Pin) error {
func (s *Strategy) checkRequiredInvestmentByQuantity(baseInvestment, quoteInvestment, baseBalance, quoteBalance, quantity, lastPrice fixedpoint.Value, pins []Pin) (requiredBase, requiredQuote fixedpoint.Value, err error) {
if baseInvestment.Compare(baseBalance) > 0 {
return fmt.Errorf("baseInvestment setup %f is greater than the total base balance %f", baseInvestment.Float64(), baseBalance.Float64())
return fixedpoint.Zero, fixedpoint.Zero, fmt.Errorf("baseInvestment setup %f is greater than the total base balance %f", baseInvestment.Float64(), baseBalance.Float64())
}
if quoteInvestment.Compare(quoteBalance) > 0 {
return fmt.Errorf("quoteInvestment setup %f is greater than the total quote balance %f", quoteInvestment.Float64(), quoteBalance.Float64())
return fixedpoint.Zero, fixedpoint.Zero, fmt.Errorf("quoteInvestment setup %f is greater than the total quote balance %f", quoteInvestment.Float64(), quoteBalance.Float64())
}
// check more investment budget details
requiredBase := fixedpoint.Zero
requiredQuote := fixedpoint.Zero
for i := len(pins) - 1; i >= 0; i++ {
requiredBase = fixedpoint.Zero
requiredQuote = fixedpoint.Zero
// when we need to place a buy-to-sell conversion order, we need to mark the price
buyPlacedPrice := fixedpoint.Zero
for i := len(pins) - 1; i >= 0; i-- {
pin := pins[i]
price := fixedpoint.Value(pin)
@ -203,31 +206,31 @@ func (s *Strategy) checkRequiredInvestmentByQuantity(baseInvestment, quoteInvest
if price.Compare(lastPrice) >= 0 {
// for orders that sell
// if we still have the base balance
if requiredBase.Compare(baseBalance) < 0 {
if requiredBase.Add(quantity).Compare(baseBalance) <= 0 {
requiredBase = requiredBase.Add(quantity)
} else if i > 0 { // we do not want to sell at i == 0
// convert sell to buy quote and add to requiredQuote
nextLowerPin := s.grid.Pins[i-1]
nextLowerPin := pins[i-1]
nextLowerPrice := fixedpoint.Value(nextLowerPin)
requiredQuote = requiredQuote.Add(quantity.Mul(nextLowerPrice))
buyPlacedPrice = nextLowerPrice
}
} else {
// for orders that buy
if price.Compare(buyPlacedPrice) == 0 {
continue
}
requiredQuote = requiredQuote.Add(quantity.Mul(price))
}
}
if requiredBase.Compare(baseBalance) > 0 && requiredQuote.Compare(quoteBalance) > 0 {
return fmt.Errorf("both base balance (%f %s) and quote balance (%f %s) are not enought",
return requiredBase, requiredQuote, fmt.Errorf("both base balance (%f %s) and quote balance (%f %s) are not enough",
baseBalance.Float64(), s.Market.BaseCurrency,
quoteBalance.Float64(), s.Market.QuoteCurrency)
}
if requiredBase.Compare(baseBalance) < 0 {
// see if we can convert some quotes to base
}
return nil
return requiredBase, requiredQuote, nil
}
func (s *Strategy) setupGridOrders(ctx context.Context, session *bbgo.ExchangeSession) error {
@ -254,7 +257,7 @@ func (s *Strategy) setupGridOrders(ctx context.Context, session *bbgo.ExchangeSe
// if the buy order is filled, then we will submit another sell order at the higher grid.
quantityOrAmountIsSet := s.QuantityOrAmount.IsSet()
if quantityOrAmountIsSet {
if err2 := s.checkRequiredInvestmentByQuantity(
if _, _, err2 := s.checkRequiredInvestmentByQuantity(
s.BaseInvestment, s.QuoteInvestment,
totalBase, totalQuote,
lastPrice, s.QuantityOrAmount.Quantity, s.grid.Pins); err != nil {

View File

@ -10,7 +10,7 @@ func TestStrategy_checkRequiredInvestmentByQuantity(t *testing.T) {
s := &Strategy{}
t.Run("basic base balance check", func(t *testing.T) {
err := s.checkRequiredInvestmentByQuantity(number(2.0), number(10_000.0),
_, _, err := s.checkRequiredInvestmentByQuantity(number(2.0), number(10_000.0),
number(1.0), number(10_000.0),
number(0.1), number(19000.0), []Pin{})
assert.Error(t, err)
@ -18,10 +18,25 @@ func TestStrategy_checkRequiredInvestmentByQuantity(t *testing.T) {
})
t.Run("basic quote balance check", func(t *testing.T) {
err := s.checkRequiredInvestmentByQuantity(number(1.0), number(10_000.0),
_, _, err := s.checkRequiredInvestmentByQuantity(number(1.0), number(10_000.0),
number(1.0), number(100.0),
number(0.1), number(19_000.0), []Pin{})
assert.Error(t, err)
assert.EqualError(t, err, "quoteInvestment setup 10000.000000 is greater than the total quote balance 100.000000")
})
t.Run("quote to base balance conversion check", func(t *testing.T) {
_, requiredQuote, err := s.checkRequiredInvestmentByQuantity(number(0.0), number(10_000.0),
number(0.0), number(10_000.0),
number(0.1), number(13_500.0), []Pin{
Pin(number(10_000.0)), // 0.1 * 10_000 = 1000 USD (buy)
Pin(number(11_000.0)), // 0.1 * 11_000 = 1100 USD (buy)
Pin(number(12_000.0)), // 0.1 * 12_000 = 1200 USD (buy)
Pin(number(13_000.0)), // 0.1 * 13_000 = 1300 USD (buy)
Pin(number(14_000.0)), // 0.1 * 14_000 = 1400 USD (buy)
Pin(number(15_000.0)), // 0.1 * 15_000 = 1500 USD
})
assert.NoError(t, err)
assert.Equal(t, number(6000.0), requiredQuote)
})
}