grid2: fix profit spread behavior and tests

This commit is contained in:
c9s 2022-12-06 01:17:29 +08:00
parent bee528c7c5
commit a8c957fc8d
2 changed files with 48 additions and 4 deletions

View File

@ -37,6 +37,11 @@ type Strategy struct {
Symbol string `json:"symbol"`
// ProfitSpread is the fixed profit spread you want to submit the sell order
// When ProfitSpread is enabled, the grid will shift up, e.g.,
// If you opened a grid with the price range 10_000 to 20_000
// With profit spread set to 3_000
// The sell orders will be placed in the range 13_000 to 23_000
// And the buy orders will be placed in the original price range 10_000 to 20_000
ProfitSpread fixedpoint.Value `json:"profitSpread"`
// GridNum is the grid number, how many orders you want to post on the orderbook.
@ -786,6 +791,13 @@ func (s *Strategy) generateGridOrders(totalQuote, totalBase, lastPrice fixedpoin
for i := len(pins) - 1; i >= 0; i-- {
pin := pins[i]
price := fixedpoint.Value(pin)
sellPrice := price
// when profitSpread is set, the sell price is shift upper with the given spread
if s.ProfitSpread.Sign() > 0 {
sellPrice = sellPrice.Add(s.ProfitSpread)
}
quantity := s.QuantityOrAmount.Quantity
if quantity.IsZero() {
quantity = s.QuantityOrAmount.Amount.Div(price)
@ -799,7 +811,7 @@ func (s *Strategy) generateGridOrders(totalQuote, totalBase, lastPrice fixedpoin
Symbol: s.Symbol,
Type: types.OrderTypeLimit,
Side: types.SideTypeSell,
Price: price,
Price: sellPrice,
Quantity: quantity,
Market: s.Market,
TimeInForce: types.TimeInForceGTC,
@ -826,7 +838,7 @@ func (s *Strategy) generateGridOrders(totalQuote, totalBase, lastPrice fixedpoin
// skip i == 0
}
} else {
if i+1 == si {
if s.ProfitSpread.IsZero() && i+1 == si {
continue
}

View File

@ -56,8 +56,8 @@ type PriceSideAssert struct {
func assertPriceSide(t *testing.T, priceSideAsserts []PriceSideAssert, orders []types.SubmitOrder) {
for i, a := range priceSideAsserts {
assert.Equal(t, a.Side, orders[i].Side)
assert.Equal(t, a.Price, orders[i].Price)
assert.Equalf(t, a.Price, orders[i].Price, "order #%d price should be %f", i+1, a.Price.Float64())
assert.Equalf(t, a.Side, orders[i].Side, "order at price %f should be %s", a.Price.Float64(), a.Side)
}
}
@ -149,6 +149,38 @@ func TestStrategy_generateGridOrders(t *testing.T) {
}, orders)
})
t.Run("enough base + quote + profitSpread", func(t *testing.T) {
s := newTestStrategy()
s.ProfitSpread = number(1_000)
s.grid = NewGrid(s.LowerPrice, s.UpperPrice, fixedpoint.NewFromInt(s.GridNum), s.Market.TickSize)
s.grid.CalculateArithmeticPins()
s.QuantityOrAmount.Quantity = number(0.01)
lastPrice := number(15300)
orders, err := s.generateGridOrders(number(10000.0), number(1.0), lastPrice)
assert.NoError(t, err)
if !assert.Equal(t, 11, len(orders)) {
for _, o := range orders {
t.Logf("- %s %s", o.Price.String(), o.Side)
}
}
assertPriceSide(t, []PriceSideAssert{
{number(21000.0), types.SideTypeSell},
{number(20000.0), types.SideTypeSell},
{number(19000.0), types.SideTypeSell},
{number(18000.0), types.SideTypeSell},
{number(17000.0), types.SideTypeSell},
{number(15000.0), types.SideTypeBuy},
{number(14000.0), types.SideTypeBuy},
{number(13000.0), types.SideTypeBuy},
{number(12000.0), types.SideTypeBuy},
{number(11000.0), types.SideTypeBuy},
{number(10000.0), types.SideTypeBuy},
}, orders)
})
}
func TestStrategy_checkRequiredInvestmentByAmount(t *testing.T) {