mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-22 14:55:16 +00:00
grid2: fix extendLowerPrice method and tests
This commit is contained in:
parent
75c088eb9c
commit
f98c00b7aa
|
@ -17,6 +17,9 @@ type Grid struct {
|
|||
// TickSize is the price tick size, this is used for truncating price
|
||||
TickSize fixedpoint.Value `json:"tickSize"`
|
||||
|
||||
// Spread is a immutable number
|
||||
Spread fixedpoint.Value `json:"spread"`
|
||||
|
||||
// Pins are the pinned grid prices, from low to high
|
||||
Pins []Pin `json:"pins"`
|
||||
|
||||
|
@ -46,14 +49,17 @@ func buildPinCache(pins []Pin) map[Pin]struct{} {
|
|||
}
|
||||
|
||||
func NewGrid(lower, upper, size, tickSize fixedpoint.Value) *Grid {
|
||||
height := upper.Sub(lower)
|
||||
spread := height.Div(size)
|
||||
|
||||
grid := &Grid{
|
||||
UpperPrice: upper,
|
||||
LowerPrice: lower,
|
||||
Size: size,
|
||||
TickSize: tickSize,
|
||||
Spread: spread,
|
||||
}
|
||||
|
||||
var spread = grid.Spread()
|
||||
var pins = calculateArithmeticPins(lower, upper, spread, tickSize)
|
||||
grid.addPins(pins)
|
||||
return grid
|
||||
|
@ -63,11 +69,6 @@ func (g *Grid) Height() fixedpoint.Value {
|
|||
return g.UpperPrice.Sub(g.LowerPrice)
|
||||
}
|
||||
|
||||
// Spread returns the spread of each grid
|
||||
func (g *Grid) Spread() fixedpoint.Value {
|
||||
return g.Height().Div(g.Size)
|
||||
}
|
||||
|
||||
func (g *Grid) Above(price fixedpoint.Value) bool {
|
||||
return price.Compare(g.UpperPrice) > 0
|
||||
}
|
||||
|
@ -86,31 +87,34 @@ func (g *Grid) HasPin(pin Pin) (ok bool) {
|
|||
}
|
||||
|
||||
func (g *Grid) ExtendUpperPrice(upper fixedpoint.Value) (newPins []Pin) {
|
||||
spread := g.Spread()
|
||||
|
||||
startPrice := g.UpperPrice.Add(spread)
|
||||
for p := startPrice; p.Compare(upper) <= 0; p = p.Add(spread) {
|
||||
newPins = append(newPins, Pin(p))
|
||||
}
|
||||
|
||||
newPins = calculateArithmeticPins(g.UpperPrice, upper, g.Spread, g.TickSize)
|
||||
g.UpperPrice = upper
|
||||
g.addPins(newPins)
|
||||
return newPins
|
||||
}
|
||||
|
||||
func (g *Grid) ExtendLowerPrice(lower fixedpoint.Value) (newPins []Pin) {
|
||||
spread := g.Spread()
|
||||
|
||||
startPrice := g.LowerPrice.Sub(spread)
|
||||
for p := startPrice; p.Compare(lower) >= 0; p = p.Sub(spread) {
|
||||
newPins = append(newPins, Pin(p))
|
||||
if lower.Compare(g.LowerPrice) >= 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
n := g.LowerPrice.Sub(lower).Div(g.Spread).Floor()
|
||||
lower = g.LowerPrice.Sub(g.Spread.Mul(n))
|
||||
newPins = calculateArithmeticPins(lower, g.LowerPrice.Sub(g.Spread), g.Spread, g.TickSize)
|
||||
|
||||
g.LowerPrice = lower
|
||||
g.addPins(newPins)
|
||||
return newPins
|
||||
}
|
||||
|
||||
func (g *Grid) TopPin() Pin {
|
||||
return g.Pins[len(g.Pins)-1]
|
||||
}
|
||||
|
||||
func (g *Grid) BottomPin() Pin {
|
||||
return g.Pins[0]
|
||||
}
|
||||
|
||||
func (g *Grid) addPins(pins []Pin) {
|
||||
g.Pins = append(g.Pins, pins...)
|
||||
|
||||
|
|
|
@ -45,48 +45,50 @@ func TestGrid_HasPin(t *testing.T) {
|
|||
func TestGrid_ExtendUpperPrice(t *testing.T) {
|
||||
upper := number(500.0)
|
||||
lower := number(100.0)
|
||||
size := number(100.0)
|
||||
grid := NewGrid(lower, upper, size, number(2.0))
|
||||
|
||||
size := number(40.0)
|
||||
grid := NewGrid(lower, upper, size, number(0.01))
|
||||
originalSpread := grid.Spread
|
||||
|
||||
assert.Equal(t, number(10.0), originalSpread)
|
||||
assert.Len(t, grid.Pins, 40) // (1000-500) / 4
|
||||
|
||||
newPins := grid.ExtendUpperPrice(number(1000.0))
|
||||
assert.Equal(t, originalSpread, grid.Spread)
|
||||
assert.Len(t, newPins, 125) // (1000-500) / 4
|
||||
assert.Equal(t, fixedpoint.NewFromFloat(4), grid.Spread)
|
||||
if assert.Len(t, grid.Pins, 226) {
|
||||
assert.Equal(t, fixedpoint.NewFromFloat(100.0), grid.Pins[0])
|
||||
assert.Equal(t, fixedpoint.NewFromFloat(1000.0), grid.Pins[225])
|
||||
}
|
||||
assert.Len(t, newPins, 51) // (1000-500) / 4
|
||||
}
|
||||
|
||||
func TestGrid_ExtendLowerPrice(t *testing.T) {
|
||||
upper := fixedpoint.NewFromFloat(3000.0)
|
||||
lower := fixedpoint.NewFromFloat(2000.0)
|
||||
size := fixedpoint.NewFromFloat(100.0)
|
||||
grid := NewGrid(lower, upper, size, number(2.0))
|
||||
size := fixedpoint.NewFromFloat(10.0)
|
||||
grid := NewGrid(lower, upper, size, number(0.01))
|
||||
|
||||
// spread = (3000 - 2000) / 100.0
|
||||
expectedSpread := fixedpoint.NewFromFloat(10.0)
|
||||
assert.Equal(t, Pin(number(2000.0)), grid.BottomPin(), "bottom pin should be 1000.0")
|
||||
assert.Equal(t, Pin(number(3000.0)), grid.TopPin(), "top pin should be 3000.0")
|
||||
assert.Len(t, grid.Pins, 11)
|
||||
|
||||
// spread = (3000 - 2000) / 10.0
|
||||
expectedSpread := fixedpoint.NewFromFloat(100.0)
|
||||
assert.Equal(t, expectedSpread, grid.Spread)
|
||||
|
||||
originalSpread := grid.Spread
|
||||
newPins := grid.ExtendLowerPrice(fixedpoint.NewFromFloat(1000.0))
|
||||
assert.Equal(t, originalSpread, grid.Spread)
|
||||
|
||||
t.Logf("newPins: %+v", newPins)
|
||||
|
||||
// 100 = (2000-1000) / 10
|
||||
if assert.Len(t, newPins, 100) {
|
||||
assert.Equal(t, fixedpoint.NewFromFloat(2000.0)-expectedSpread, newPins[99])
|
||||
if assert.Len(t, newPins, 10) {
|
||||
assert.Equal(t, Pin(number(1000.0)), newPins[0])
|
||||
assert.Equal(t, Pin(number(1900.0)), newPins[len(newPins)-1])
|
||||
}
|
||||
|
||||
assert.Equal(t, expectedSpread, grid.Spread)
|
||||
if assert.Len(t, grid.Pins, 201) {
|
||||
assert.Equal(t, fixedpoint.NewFromFloat(1000.0), grid.Pins[0])
|
||||
assert.Equal(t, fixedpoint.NewFromFloat(3000.0), grid.Pins[200])
|
||||
}
|
||||
|
||||
newPins2 := grid.ExtendLowerPrice(
|
||||
fixedpoint.NewFromFloat(1000.0 - 1.0))
|
||||
assert.Len(t, newPins2, 0) // should have no new pin generated
|
||||
if assert.Len(t, grid.Pins, 21) {
|
||||
assert.Equal(t, Pin(number(1000.0)), grid.BottomPin(), "bottom pin should be 1000.0")
|
||||
assert.Equal(t, Pin(number(3000.0)), grid.TopPin(), "top pin should be 3000.0")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_calculateArithmeticPins(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user