mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
grid2: respect s.BaseGridNum and add a failing test case
This commit is contained in:
parent
cdebcc9a58
commit
6cce5a2268
|
@ -796,6 +796,8 @@ func (s *Strategy) calculateBaseQuoteInvestmentQuantity(
|
||||||
if numberOfSellOrders > 0 {
|
if numberOfSellOrders > 0 {
|
||||||
numberOfSellOrders--
|
numberOfSellOrders--
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.logger.Infof("calculated number of sell orders: %d", numberOfSellOrders)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the maxBaseQuantity is less than minQuantity, then we need to reduce the number of the sell orders
|
// if the maxBaseQuantity is less than minQuantity, then we need to reduce the number of the sell orders
|
||||||
|
@ -810,8 +812,12 @@ func (s *Strategy) calculateBaseQuoteInvestmentQuantity(
|
||||||
s.Market.MinQuantity)
|
s.Market.MinQuantity)
|
||||||
|
|
||||||
if baseQuantity.Compare(minBaseQuantity) <= 0 {
|
if baseQuantity.Compare(minBaseQuantity) <= 0 {
|
||||||
|
s.logger.Infof("base quantity %s is less than min base quantity: %s, adjusting...", baseQuantity.String(), minBaseQuantity.String())
|
||||||
|
|
||||||
baseQuantity = s.Market.RoundUpQuantityByPrecision(minBaseQuantity)
|
baseQuantity = s.Market.RoundUpQuantityByPrecision(minBaseQuantity)
|
||||||
numberOfSellOrders = int(math.Floor(baseInvestment.Div(baseQuantity).Float64()))
|
numberOfSellOrders = int(math.Floor(baseInvestment.Div(baseQuantity).Float64()))
|
||||||
|
|
||||||
|
s.logger.Infof("adjusted base quantity to %s", baseQuantity.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
s.logger.Infof("grid base investment sell orders: %d", numberOfSellOrders)
|
s.logger.Infof("grid base investment sell orders: %d", numberOfSellOrders)
|
||||||
|
@ -824,7 +830,8 @@ func (s *Strategy) calculateBaseQuoteInvestmentQuantity(
|
||||||
// quoteInvestment = (p1 + p2 + p3) * q
|
// quoteInvestment = (p1 + p2 + p3) * q
|
||||||
// maxBuyQuantity = quoteInvestment / (p1 + p2 + p3)
|
// maxBuyQuantity = quoteInvestment / (p1 + p2 + p3)
|
||||||
si := -1
|
si := -1
|
||||||
for i := len(pins) - 1 - numberOfSellOrders; i >= 0; i-- {
|
end := len(pins) - 1
|
||||||
|
for i := end - numberOfSellOrders - 1; i >= 0; i-- {
|
||||||
pin := pins[i]
|
pin := pins[i]
|
||||||
price := fixedpoint.Value(pin)
|
price := fixedpoint.Value(pin)
|
||||||
|
|
||||||
|
@ -844,6 +851,7 @@ func (s *Strategy) calculateBaseQuoteInvestmentQuantity(
|
||||||
// requiredQuote = requiredQuote.Add(quantity.Mul(nextLowerPrice))
|
// requiredQuote = requiredQuote.Add(quantity.Mul(nextLowerPrice))
|
||||||
totalQuotePrice = totalQuotePrice.Add(nextLowerPrice)
|
totalQuotePrice = totalQuotePrice.Add(nextLowerPrice)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// for orders that buy
|
// for orders that buy
|
||||||
if s.ProfitSpread.IsZero() && i+1 == si {
|
if s.ProfitSpread.IsZero() && i+1 == si {
|
||||||
|
@ -851,7 +859,7 @@ func (s *Strategy) calculateBaseQuoteInvestmentQuantity(
|
||||||
}
|
}
|
||||||
|
|
||||||
// should never place a buy order at the upper price
|
// should never place a buy order at the upper price
|
||||||
if i == len(pins)-1 {
|
if i == end {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -859,8 +867,11 @@ func (s *Strategy) calculateBaseQuoteInvestmentQuantity(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.logger.Infof("total quote price: %f", totalQuotePrice.Float64())
|
||||||
if totalQuotePrice.Sign() > 0 && quoteInvestment.Sign() > 0 {
|
if totalQuotePrice.Sign() > 0 && quoteInvestment.Sign() > 0 {
|
||||||
quoteSideQuantity := quoteInvestment.Div(totalQuotePrice)
|
quoteSideQuantity := quoteInvestment.Div(totalQuotePrice)
|
||||||
|
|
||||||
|
s.logger.Infof("quote side quantity: %f = %f / %f", quoteSideQuantity.Float64(), quoteInvestment.Float64(), totalQuotePrice.Float64())
|
||||||
if numberOfSellOrders > 0 {
|
if numberOfSellOrders > 0 {
|
||||||
return fixedpoint.Min(quoteSideQuantity, baseQuantity), nil
|
return fixedpoint.Min(quoteSideQuantity, baseQuantity), nil
|
||||||
}
|
}
|
||||||
|
@ -1058,6 +1069,11 @@ func (s *Strategy) openGrid(ctx context.Context, session *bbgo.ExchangeSession)
|
||||||
return err2
|
return err2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.BaseGridNum > 0 {
|
||||||
|
sell1 := fixedpoint.Value(s.grid.Pins[len(s.grid.Pins)-1-s.BaseGridNum])
|
||||||
|
lastPrice = sell1.Sub(s.Market.TickSize)
|
||||||
|
}
|
||||||
|
|
||||||
// check if base and quote are enough
|
// check if base and quote are enough
|
||||||
var totalBase = fixedpoint.Zero
|
var totalBase = fixedpoint.Zero
|
||||||
var totalQuote = fixedpoint.Zero
|
var totalQuote = fixedpoint.Zero
|
||||||
|
@ -1432,6 +1448,8 @@ func calculateMinimalQuoteInvestment(market types.Market, grid *Grid) fixedpoint
|
||||||
for i := len(pins) - 2; i >= 0; i-- {
|
for i := len(pins) - 2; i >= 0; i-- {
|
||||||
pin := pins[i]
|
pin := pins[i]
|
||||||
price := fixedpoint.Value(pin)
|
price := fixedpoint.Value(pin)
|
||||||
|
|
||||||
|
// TODO: should we round the quote here before adding?
|
||||||
totalQuote = totalQuote.Add(price.Mul(minQuantity))
|
totalQuote = totalQuote.Add(price.Mul(minQuantity))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -204,6 +204,65 @@ func TestStrategy_generateGridOrders(t *testing.T) {
|
||||||
}, orders)
|
}, orders)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("base and quote #2", func(t *testing.T) {
|
||||||
|
gridNum := int64(22)
|
||||||
|
upperPrice := number(35500.000000)
|
||||||
|
lowerPrice := number(34450.000000)
|
||||||
|
quoteInvestment := number(18.47)
|
||||||
|
baseInvestment := number(0.010700)
|
||||||
|
lastPrice := number(34522.930000)
|
||||||
|
baseGridNum := int(20)
|
||||||
|
|
||||||
|
s := newTestStrategy()
|
||||||
|
s.GridNum = gridNum
|
||||||
|
s.BaseGridNum = baseGridNum
|
||||||
|
s.LowerPrice = lowerPrice
|
||||||
|
s.UpperPrice = upperPrice
|
||||||
|
s.grid = NewGrid(lowerPrice, upperPrice, fixedpoint.NewFromInt(s.GridNum), s.Market.TickSize)
|
||||||
|
s.grid.CalculateArithmeticPins()
|
||||||
|
assert.Equal(t, 22, len(s.grid.Pins))
|
||||||
|
|
||||||
|
quantity, err := s.calculateBaseQuoteInvestmentQuantity(quoteInvestment, baseInvestment, lastPrice, s.grid.Pins)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "0.000535", quantity.String())
|
||||||
|
|
||||||
|
s.QuantityOrAmount.Quantity = quantity
|
||||||
|
|
||||||
|
orders, err := s.generateGridOrders(quoteInvestment, baseInvestment, lastPrice)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if !assert.Equal(t, 21, len(orders)) {
|
||||||
|
for _, o := range orders {
|
||||||
|
t.Logf("- %s %s", o.Price.String(), o.Side)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertPriceSide(t, []PriceSideAssert{
|
||||||
|
{number(35500.0), types.SideTypeSell},
|
||||||
|
{number(35450.0), types.SideTypeSell},
|
||||||
|
{number(35400.0), types.SideTypeSell},
|
||||||
|
{number(35350.0), types.SideTypeSell},
|
||||||
|
{number(35300.0), types.SideTypeSell},
|
||||||
|
{number(35250.0), types.SideTypeSell},
|
||||||
|
{number(35200.0), types.SideTypeSell},
|
||||||
|
{number(35150.0), types.SideTypeSell},
|
||||||
|
{number(35100.0), types.SideTypeSell},
|
||||||
|
{number(35050.0), types.SideTypeSell},
|
||||||
|
{number(35000.0), types.SideTypeSell},
|
||||||
|
{number(34950.0), types.SideTypeSell},
|
||||||
|
{number(34900.0), types.SideTypeSell},
|
||||||
|
{number(34850.0), types.SideTypeSell},
|
||||||
|
{number(34800.0), types.SideTypeSell},
|
||||||
|
{number(34750.0), types.SideTypeSell},
|
||||||
|
{number(34700.0), types.SideTypeSell},
|
||||||
|
{number(34650.0), types.SideTypeSell},
|
||||||
|
{number(34600.0), types.SideTypeSell},
|
||||||
|
{number(34550.0), types.SideTypeSell},
|
||||||
|
// -- fake trade price at 34549.9
|
||||||
|
// -- 34500 should be empty
|
||||||
|
{number(34450.0), types.SideTypeBuy},
|
||||||
|
}, orders)
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("base and quote with pre-calculated baseGridNumber", func(t *testing.T) {
|
t.Run("base and quote with pre-calculated baseGridNumber", func(t *testing.T) {
|
||||||
s := newTestStrategy()
|
s := newTestStrategy()
|
||||||
s.grid = NewGrid(s.LowerPrice, s.UpperPrice, fixedpoint.NewFromInt(s.GridNum), s.Market.TickSize)
|
s.grid = NewGrid(s.LowerPrice, s.UpperPrice, fixedpoint.NewFromInt(s.GridNum), s.Market.TickSize)
|
||||||
|
@ -519,11 +578,11 @@ func newTestMarket(symbol string) types.Market {
|
||||||
BaseCurrency: "BTC",
|
BaseCurrency: "BTC",
|
||||||
QuoteCurrency: "USDT",
|
QuoteCurrency: "USDT",
|
||||||
TickSize: number(0.01),
|
TickSize: number(0.01),
|
||||||
StepSize: number(0.00001),
|
StepSize: number(0.000001),
|
||||||
PricePrecision: 2,
|
PricePrecision: 2,
|
||||||
VolumePrecision: 8,
|
VolumePrecision: 8,
|
||||||
MinNotional: number(10.0),
|
MinNotional: number(8.0),
|
||||||
MinQuantity: number(0.001),
|
MinQuantity: number(0.0003),
|
||||||
}
|
}
|
||||||
case "ETHUSDT":
|
case "ETHUSDT":
|
||||||
return types.Market{
|
return types.Market{
|
||||||
|
@ -534,7 +593,7 @@ func newTestMarket(symbol string) types.Market {
|
||||||
PricePrecision: 2,
|
PricePrecision: 2,
|
||||||
VolumePrecision: 6,
|
VolumePrecision: 6,
|
||||||
MinNotional: number(8.000),
|
MinNotional: number(8.000),
|
||||||
MinQuantity: number(0.00030),
|
MinQuantity: number(0.0046),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,12 +636,17 @@ func newTestOrder(price, quantity fixedpoint.Value, side types.SideType) types.O
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestStrategy() *Strategy {
|
func newTestStrategy(va ...string) *Strategy {
|
||||||
market := newTestMarket("BTCUSDT")
|
symbol := "BTCUSDT"
|
||||||
|
|
||||||
|
if len(va) > 0 {
|
||||||
|
symbol = va[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
market := newTestMarket(symbol)
|
||||||
s := &Strategy{
|
s := &Strategy{
|
||||||
logger: logrus.NewEntry(logrus.New()),
|
logger: logrus.NewEntry(logrus.New()),
|
||||||
Symbol: "BTCUSDT",
|
Symbol: symbol,
|
||||||
Market: market,
|
Market: market,
|
||||||
GridProfitStats: newGridProfitStats(market),
|
GridProfitStats: newGridProfitStats(market),
|
||||||
UpperPrice: number(20_000),
|
UpperPrice: number(20_000),
|
||||||
|
@ -790,7 +854,9 @@ func TestStrategy_handleOrderFilled(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
orderExecutor := gridmocks.NewMockOrderExecutor(mockCtrl)
|
orderExecutor := gridmocks.NewMockOrderExecutor(mockCtrl)
|
||||||
orderExecutor.EXPECT().SubmitOrders(ctx, gomock.Any()).DoAndReturn(func(ctx context.Context, order types.SubmitOrder) (types.OrderSlice, error) {
|
orderExecutor.EXPECT().SubmitOrders(ctx, gomock.Any()).DoAndReturn(func(
|
||||||
|
ctx context.Context, order types.SubmitOrder,
|
||||||
|
) (types.OrderSlice, error) {
|
||||||
assert.True(t, equalOrdersIgnoreClientOrderID(expectedSubmitOrder, order), "%+v is not equal to %+v", order, expectedSubmitOrder)
|
assert.True(t, equalOrdersIgnoreClientOrderID(expectedSubmitOrder, order), "%+v is not equal to %+v", order, expectedSubmitOrder)
|
||||||
return []types.Order{
|
return []types.Order{
|
||||||
{SubmitOrder: expectedSubmitOrder},
|
{SubmitOrder: expectedSubmitOrder},
|
||||||
|
@ -858,7 +924,9 @@ func TestStrategy_handleOrderFilled(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
orderExecutor := gridmocks.NewMockOrderExecutor(mockCtrl)
|
orderExecutor := gridmocks.NewMockOrderExecutor(mockCtrl)
|
||||||
orderExecutor.EXPECT().SubmitOrders(ctx, gomock.Any()).DoAndReturn(func(ctx context.Context, order types.SubmitOrder) (types.OrderSlice, error) {
|
orderExecutor.EXPECT().SubmitOrders(ctx, gomock.Any()).DoAndReturn(func(
|
||||||
|
ctx context.Context, order types.SubmitOrder,
|
||||||
|
) (types.OrderSlice, error) {
|
||||||
assert.True(t, equalOrdersIgnoreClientOrderID(expectedSubmitOrder, order), "%+v is not equal to %+v", order, expectedSubmitOrder)
|
assert.True(t, equalOrdersIgnoreClientOrderID(expectedSubmitOrder, order), "%+v is not equal to %+v", order, expectedSubmitOrder)
|
||||||
return []types.Order{
|
return []types.Order{
|
||||||
{SubmitOrder: expectedSubmitOrder},
|
{SubmitOrder: expectedSubmitOrder},
|
||||||
|
@ -946,7 +1014,9 @@ func TestStrategy_handleOrderFilled(t *testing.T) {
|
||||||
Market: s.Market,
|
Market: s.Market,
|
||||||
Tag: orderTag,
|
Tag: orderTag,
|
||||||
}
|
}
|
||||||
orderExecutor.EXPECT().SubmitOrders(ctx, gomock.Any()).DoAndReturn(func(ctx context.Context, order types.SubmitOrder) (types.OrderSlice, error) {
|
orderExecutor.EXPECT().SubmitOrders(ctx, gomock.Any()).DoAndReturn(func(
|
||||||
|
ctx context.Context, order types.SubmitOrder,
|
||||||
|
) (types.OrderSlice, error) {
|
||||||
assert.True(t, equalOrdersIgnoreClientOrderID(expectedSubmitOrder, order), "%+v is not equal to %+v", order, expectedSubmitOrder)
|
assert.True(t, equalOrdersIgnoreClientOrderID(expectedSubmitOrder, order), "%+v is not equal to %+v", order, expectedSubmitOrder)
|
||||||
return []types.Order{
|
return []types.Order{
|
||||||
{SubmitOrder: expectedSubmitOrder},
|
{SubmitOrder: expectedSubmitOrder},
|
||||||
|
@ -963,7 +1033,9 @@ func TestStrategy_handleOrderFilled(t *testing.T) {
|
||||||
Market: s.Market,
|
Market: s.Market,
|
||||||
Tag: orderTag,
|
Tag: orderTag,
|
||||||
}
|
}
|
||||||
orderExecutor.EXPECT().SubmitOrders(ctx, gomock.Any()).DoAndReturn(func(ctx context.Context, order types.SubmitOrder) (types.OrderSlice, error) {
|
orderExecutor.EXPECT().SubmitOrders(ctx, gomock.Any()).DoAndReturn(func(
|
||||||
|
ctx context.Context, order types.SubmitOrder,
|
||||||
|
) (types.OrderSlice, error) {
|
||||||
assert.True(t, equalOrdersIgnoreClientOrderID(expectedSubmitOrder2, order), "%+v is not equal to %+v", order, expectedSubmitOrder2)
|
assert.True(t, equalOrdersIgnoreClientOrderID(expectedSubmitOrder2, order), "%+v is not equal to %+v", order, expectedSubmitOrder2)
|
||||||
return []types.Order{
|
return []types.Order{
|
||||||
{SubmitOrder: expectedSubmitOrder2},
|
{SubmitOrder: expectedSubmitOrder2},
|
||||||
|
@ -1060,7 +1132,9 @@ func TestStrategy_handleOrderFilled(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
orderExecutor := gridmocks.NewMockOrderExecutor(mockCtrl)
|
orderExecutor := gridmocks.NewMockOrderExecutor(mockCtrl)
|
||||||
orderExecutor.EXPECT().SubmitOrders(ctx, gomock.Any()).DoAndReturn(func(ctx context.Context, order types.SubmitOrder) (types.OrderSlice, error) {
|
orderExecutor.EXPECT().SubmitOrders(ctx, gomock.Any()).DoAndReturn(func(
|
||||||
|
ctx context.Context, order types.SubmitOrder,
|
||||||
|
) (types.OrderSlice, error) {
|
||||||
assert.True(t, equalOrdersIgnoreClientOrderID(expectedSubmitOrder, order), "%+v is not equal to %+v", order, expectedSubmitOrder)
|
assert.True(t, equalOrdersIgnoreClientOrderID(expectedSubmitOrder, order), "%+v is not equal to %+v", order, expectedSubmitOrder)
|
||||||
return []types.Order{
|
return []types.Order{
|
||||||
{SubmitOrder: expectedSubmitOrder},
|
{SubmitOrder: expectedSubmitOrder},
|
||||||
|
@ -1078,7 +1152,9 @@ func TestStrategy_handleOrderFilled(t *testing.T) {
|
||||||
Tag: orderTag,
|
Tag: orderTag,
|
||||||
}
|
}
|
||||||
|
|
||||||
orderExecutor.EXPECT().SubmitOrders(ctx, gomock.Any()).DoAndReturn(func(ctx context.Context, order types.SubmitOrder) (types.OrderSlice, error) {
|
orderExecutor.EXPECT().SubmitOrders(ctx, gomock.Any()).DoAndReturn(func(
|
||||||
|
ctx context.Context, order types.SubmitOrder,
|
||||||
|
) (types.OrderSlice, error) {
|
||||||
assert.True(t, equalOrdersIgnoreClientOrderID(expectedSubmitOrder2, order), "%+v is not equal to %+v", order, expectedSubmitOrder2)
|
assert.True(t, equalOrdersIgnoreClientOrderID(expectedSubmitOrder2, order), "%+v is not equal to %+v", order, expectedSubmitOrder2)
|
||||||
return []types.Order{
|
return []types.Order{
|
||||||
{SubmitOrder: expectedSubmitOrder2},
|
{SubmitOrder: expectedSubmitOrder2},
|
||||||
|
@ -1190,14 +1266,14 @@ func TestStrategy_aggregateOrderQuoteAmountAndFeeRetry(t *testing.T) {
|
||||||
func TestStrategy_checkMinimalQuoteInvestment(t *testing.T) {
|
func TestStrategy_checkMinimalQuoteInvestment(t *testing.T) {
|
||||||
|
|
||||||
t.Run("7 grids", func(t *testing.T) {
|
t.Run("7 grids", func(t *testing.T) {
|
||||||
s := newTestStrategy()
|
s := newTestStrategy("ETHUSDT")
|
||||||
s.UpperPrice = number(1660)
|
s.UpperPrice = number(1660)
|
||||||
s.LowerPrice = number(1630)
|
s.LowerPrice = number(1630)
|
||||||
s.QuoteInvestment = number(61)
|
s.QuoteInvestment = number(61)
|
||||||
s.GridNum = 7
|
s.GridNum = 7
|
||||||
grid := s.newGrid()
|
grid := s.newGrid()
|
||||||
minQuoteInvestment := calculateMinimalQuoteInvestment(s.Market, grid)
|
minQuoteInvestment := calculateMinimalQuoteInvestment(s.Market, grid)
|
||||||
assert.InDelta(t, 60.46, minQuoteInvestment.Float64(), 0.01)
|
assert.InDelta(t, 48.36, minQuoteInvestment.Float64(), 0.01)
|
||||||
|
|
||||||
err := s.checkMinimalQuoteInvestment(grid)
|
err := s.checkMinimalQuoteInvestment(grid)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
@ -1207,12 +1283,11 @@ func TestStrategy_checkMinimalQuoteInvestment(t *testing.T) {
|
||||||
s := newTestStrategy()
|
s := newTestStrategy()
|
||||||
// 10_000 * 0.001 = 10USDT
|
// 10_000 * 0.001 = 10USDT
|
||||||
// 20_000 * 0.001 = 20USDT
|
// 20_000 * 0.001 = 20USDT
|
||||||
// hence we should have at least: 20USDT * 10 grids
|
|
||||||
s.QuoteInvestment = number(10_000)
|
s.QuoteInvestment = number(10_000)
|
||||||
s.GridNum = 10
|
s.GridNum = 10
|
||||||
grid := s.newGrid()
|
grid := s.newGrid()
|
||||||
minQuoteInvestment := calculateMinimalQuoteInvestment(s.Market, grid)
|
minQuoteInvestment := calculateMinimalQuoteInvestment(s.Market, grid)
|
||||||
assert.InDelta(t, 129.9999, minQuoteInvestment.Float64(), 0.01)
|
assert.InDelta(t, 103.999, minQuoteInvestment.Float64(), 0.01)
|
||||||
|
|
||||||
err := s.checkMinimalQuoteInvestment(grid)
|
err := s.checkMinimalQuoteInvestment(grid)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
@ -1225,11 +1300,11 @@ func TestStrategy_checkMinimalQuoteInvestment(t *testing.T) {
|
||||||
|
|
||||||
grid := s.newGrid()
|
grid := s.newGrid()
|
||||||
minQuoteInvestment := calculateMinimalQuoteInvestment(s.Market, grid)
|
minQuoteInvestment := calculateMinimalQuoteInvestment(s.Market, grid)
|
||||||
assert.InDelta(t, 14979.995499, minQuoteInvestment.Float64(), 0.001)
|
assert.InDelta(t, 11983.996400, minQuoteInvestment.Float64(), 0.001)
|
||||||
|
|
||||||
err := s.checkMinimalQuoteInvestment(grid)
|
err := s.checkMinimalQuoteInvestment(grid)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.EqualError(t, err, "need at least 14979.995500 USDT for quote investment, 10000.000000 USDT given")
|
assert.EqualError(t, err, "need at least 11983.996400 USDT for quote investment, 10000.000000 USDT given")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user