add long position test for trailing stop

Signed-off-by: c9s <yoanlin93@gmail.com>
This commit is contained in:
c9s 2022-07-06 10:54:53 +08:00
parent 03481000cc
commit b49f12300c
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54
2 changed files with 93 additions and 7 deletions

View File

@ -4,6 +4,8 @@ import (
"context" "context"
"fmt" "fmt"
log "github.com/sirupsen/logrus"
"github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
@ -51,7 +53,9 @@ func (s *TrailingStop2) Bind(session *ExchangeSession, orderExecutor *GeneralOrd
position := orderExecutor.Position() position := orderExecutor.Position()
session.MarketDataStream.OnKLineClosed(types.KLineWith(s.Symbol, s.Interval, func(kline types.KLine) { session.MarketDataStream.OnKLineClosed(types.KLineWith(s.Symbol, s.Interval, func(kline types.KLine) {
s.checkStopPrice(kline.Close, position) if err := s.checkStopPrice(kline.Close, position); err != nil {
log.WithError(err).Errorf("error")
}
})) }))
if !IsBackTesting { if !IsBackTesting {
@ -60,7 +64,9 @@ func (s *TrailingStop2) Bind(session *ExchangeSession, orderExecutor *GeneralOrd
return return
} }
s.checkStopPrice(trade.Price, position) if err := s.checkStopPrice(trade.Price, position); err != nil {
log.WithError(err).Errorf("error")
}
}) })
} }
} }
@ -129,7 +135,7 @@ func (s *TrailingStop2) checkStopPrice(price fixedpoint.Value, position *types.P
case types.SideTypeSell: case types.SideTypeSell:
s.latestHigh = fixedpoint.Max(price, s.latestHigh) s.latestHigh = fixedpoint.Max(price, s.latestHigh)
change := price.Sub(s.latestHigh).Div(s.latestHigh) change := s.latestHigh.Sub(price).Div(price)
if change.Compare(s.CallbackRate) >= 0 { if change.Compare(s.CallbackRate) >= 0 {
// submit order // submit order
return s.triggerStop(price) return s.triggerStop(price)

View File

@ -27,7 +27,7 @@ func getTestMarket() types.Market {
return market return market
} }
func TestTrailingStop(t *testing.T) { func TestTrailingStop_ShortPosition(t *testing.T) {
market := getTestMarket() market := getTestMarket()
mockCtrl := gomock.NewController(t) mockCtrl := gomock.NewController(t)
@ -75,27 +75,107 @@ func TestTrailingStop(t *testing.T) {
// 20000 - 1% = 19800 // 20000 - 1% = 19800
currentPrice = currentPrice.Mul(one.Sub(activationRatio)) currentPrice = currentPrice.Mul(one.Sub(activationRatio))
assert.Equal(t, fixedpoint.NewFromFloat(19800.0), currentPrice)
err = stop.checkStopPrice(currentPrice, position) err = stop.checkStopPrice(currentPrice, position)
if assert.NoError(t, err) { if assert.NoError(t, err) {
assert.True(t, stop.activated) assert.True(t, stop.activated)
assert.Equal(t, fixedpoint.NewFromFloat(19800.0), currentPrice)
assert.Equal(t, fixedpoint.NewFromFloat(19800.0), stop.latestHigh) assert.Equal(t, fixedpoint.NewFromFloat(19800.0), stop.latestHigh)
} }
// 19800 - 1% = 19602 // 19800 - 1% = 19602
currentPrice = currentPrice.Mul(one.Sub(callbackRatio)) currentPrice = currentPrice.Mul(one.Sub(callbackRatio))
assert.Equal(t, fixedpoint.NewFromFloat(19602.0), currentPrice)
err = stop.checkStopPrice(currentPrice, position) err = stop.checkStopPrice(currentPrice, position)
if assert.NoError(t, err) { if assert.NoError(t, err) {
assert.Equal(t, fixedpoint.NewFromFloat(19602.0), currentPrice)
assert.Equal(t, fixedpoint.NewFromFloat(19602.0), stop.latestHigh) assert.Equal(t, fixedpoint.NewFromFloat(19602.0), stop.latestHigh)
assert.True(t, stop.activated) assert.True(t, stop.activated)
} }
// 19602 + 1% = 19798.02 // 19602 + 1% = 19798.02
currentPrice = currentPrice.Mul(one.Add(callbackRatio)) currentPrice = currentPrice.Mul(one.Add(callbackRatio))
assert.Equal(t, fixedpoint.NewFromFloat(19798.02), currentPrice)
err = stop.checkStopPrice(currentPrice, position)
if assert.NoError(t, err) {
assert.Equal(t, fixedpoint.Zero, stop.latestHigh)
assert.False(t, stop.activated)
}
}
func TestTrailingStop_LongPosition(t *testing.T) {
market := getTestMarket()
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockEx := mocks.NewMockExchange(mockCtrl)
mockEx.EXPECT().NewStream().Return(&types.StandardStream{}).Times(2)
mockEx.EXPECT().SubmitOrders(gomock.Any(), types.SubmitOrder{
Symbol: "BTCUSDT",
Side: types.SideTypeSell,
Type: types.OrderTypeMarket,
Market: market,
Quantity: fixedpoint.NewFromFloat(1.0),
Tag: "trailingStop",
})
session := NewExchangeSession("test", mockEx)
assert.NotNil(t, session)
session.markets[market.Symbol] = market
position := types.NewPositionFromMarket(market)
position.AverageCost = fixedpoint.NewFromFloat(20000.0)
position.Base = fixedpoint.NewFromFloat(1.0)
orderExecutor := NewGeneralOrderExecutor(session, "BTCUSDT", "test", "test-01", position)
activationRatio := fixedpoint.NewFromFloat(0.01)
callbackRatio := fixedpoint.NewFromFloat(0.01)
stop := &TrailingStop2{
Symbol: "BTCUSDT",
Interval: types.Interval1m,
Side: types.SideTypeSell,
CallbackRate: callbackRatio,
ActivationRatio: activationRatio,
}
stop.Bind(session, orderExecutor)
// the same price
currentPrice := fixedpoint.NewFromFloat(20000.0)
err := stop.checkStopPrice(currentPrice, position)
if assert.NoError(t, err) {
assert.False(t, stop.activated)
}
// 20000 + 1% = 20200
currentPrice = currentPrice.Mul(one.Add(activationRatio))
assert.Equal(t, fixedpoint.NewFromFloat(20200.0), currentPrice)
err = stop.checkStopPrice(currentPrice, position)
if assert.NoError(t, err) {
assert.True(t, stop.activated)
assert.Equal(t, fixedpoint.NewFromFloat(20200.0), stop.latestHigh)
}
// 20200 + 1% = 20402
currentPrice = currentPrice.Mul(one.Add(callbackRatio))
assert.Equal(t, fixedpoint.NewFromFloat(20402.0), currentPrice)
err = stop.checkStopPrice(currentPrice, position)
if assert.NoError(t, err) {
assert.Equal(t, fixedpoint.NewFromFloat(20402.0), stop.latestHigh)
assert.True(t, stop.activated)
}
// 20402 - 1%
currentPrice = currentPrice.Mul(one.Sub(callbackRatio))
assert.Equal(t, fixedpoint.NewFromFloat(20197.98), currentPrice)
err = stop.checkStopPrice(currentPrice, position) err = stop.checkStopPrice(currentPrice, position)
if assert.NoError(t, err) { if assert.NoError(t, err) {
assert.Equal(t, fixedpoint.NewFromFloat(19798.02), currentPrice)
assert.Equal(t, fixedpoint.Zero, stop.latestHigh) assert.Equal(t, fixedpoint.Zero, stop.latestHigh)
assert.False(t, stop.activated) assert.False(t, stop.activated)
} }