pivotshort: add init place order

This commit is contained in:
austin362667 2022-06-04 02:17:58 +08:00 committed by Austin Liu
parent 6ceb54679a
commit fcdc26e188
2 changed files with 55 additions and 47 deletions

View File

@ -33,7 +33,7 @@ exchangeStrategies:
backtest: backtest:
sessions: sessions:
- binance - binance
startTime: "2022-05-25" startTime: "2022-04-01"
endTime: "2022-06-03" endTime: "2022-06-03"
symbols: symbols:
- GMTUSDT - GMTUSDT

View File

@ -54,6 +54,7 @@ type Strategy struct {
ProfitStats *types.ProfitStats `json:"profitStats,omitempty" persistence:"profit_stats"` ProfitStats *types.ProfitStats `json:"profitStats,omitempty" persistence:"profit_stats"`
PivotLength int `json:"pivotLength"` PivotLength int `json:"pivotLength"`
LastLow fixedpoint.Value
Entry Entry Entry Entry
Exit Exit Exit Exit
@ -81,7 +82,7 @@ func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) {
//session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: types.Interval1d}) //session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: types.Interval1d})
} }
func (s *Strategy) placeOrder(ctx context.Context, marketPrice fixedpoint.Value, limitPrice fixedpoint.Value, currentPrice fixedpoint.Value, qty fixedpoint.Value, orderExecutor bbgo.OrderExecutor) { func (s *Strategy) placeOrder(ctx context.Context, lastLow fixedpoint.Value, limitPrice fixedpoint.Value, currentPrice fixedpoint.Value, qty fixedpoint.Value, orderExecutor bbgo.OrderExecutor) {
submitOrder := types.SubmitOrder{ submitOrder := types.SubmitOrder{
Symbol: s.Symbol, Symbol: s.Symbol,
Side: types.SideTypeSell, Side: types.SideTypeSell,
@ -89,7 +90,7 @@ func (s *Strategy) placeOrder(ctx context.Context, marketPrice fixedpoint.Value,
Price: limitPrice, Price: limitPrice,
Quantity: qty, Quantity: qty,
} }
if s.Entry.Immediate && marketPrice.Compare(currentPrice) <= 0 { if !lastLow.IsZero() && s.Entry.Immediate && lastLow.Compare(currentPrice) <= 0 {
submitOrder.Type = types.OrderTypeMarket submitOrder.Type = types.OrderTypeMarket
} }
if s.session.Margin { if s.session.Margin {
@ -163,6 +164,43 @@ func (s *Strategy) getValidPivotLow(price fixedpoint.Value) fixedpoint.Value {
return price return price
} }
func (s *Strategy) placeLayerOrder(ctx context.Context, lastLow fixedpoint.Value, limitPrice fixedpoint.Value, currentPrice fixedpoint.Value, orderExecutor bbgo.OrderExecutor) {
futuresMode := s.session.Futures || s.session.IsolatedFutures
d := s.Entry.CatBounceRatio.Div(s.Entry.NumLayers)
q := s.Entry.Quantity
if !s.TotalQuantity.IsZero() {
q = s.TotalQuantity.Div(s.Entry.NumLayers)
}
for i := 0; i < int(s.Entry.NumLayers.Float64()); i++ {
balances := s.session.GetAccount().Balances()
quoteBalance, _ := balances[s.Market.QuoteCurrency]
baseBalance, _ := balances[s.Market.BaseCurrency]
p := limitPrice.Mul(fixedpoint.One.Add(s.Entry.CatBounceRatio.Sub(fixedpoint.NewFromFloat(d.Float64() * float64(i)))))
if futuresMode {
//log.Infof("futures mode on")
if q.Mul(p).Compare(quoteBalance.Available) <= 0 {
s.placeOrder(ctx, lastLow, p, currentPrice, q, orderExecutor)
s.tradeCollector.Process()
}
} else if s.Environment.IsBackTesting() {
//log.Infof("spot backtest mode on")
if q.Compare(baseBalance.Available) <= 0 {
s.placeOrder(ctx, lastLow, p, currentPrice, q, orderExecutor)
s.tradeCollector.Process()
}
} else {
//log.Infof("spot mode on")
if q.Compare(baseBalance.Available) <= 0 {
s.placeOrder(ctx, lastLow, p, currentPrice, q, orderExecutor)
s.tradeCollector.Process()
}
}
}
}
func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession) error { func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession) error {
// initial required information // initial required information
s.session = session s.session = session
@ -220,17 +258,15 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
s.pivot = &indicator.Pivot{IntervalWindow: iw} s.pivot = &indicator.Pivot{IntervalWindow: iw}
s.pivot.Bind(st) s.pivot.Bind(st)
session.UserDataStream.OnStart(func() { s.LastLow = fixedpoint.Zero
log.Infof("connected")
})
var lastLow fixedpoint.Value session.UserDataStream.OnStart(func() {
futuresMode := s.session.Futures || s.session.IsolatedFutures if price, ok := session.LastPrice(s.Symbol); ok {
d := s.Entry.CatBounceRatio.Div(s.Entry.NumLayers) limitPrice := s.getValidPivotLow(price)
q := s.Entry.Quantity log.Infof("init place limit sell start from %f adds up to %f percent with %f layers of orders", limitPrice.Float64(), s.Entry.CatBounceRatio.Mul(fixedpoint.NewFromInt(100)).Float64(), s.Entry.NumLayers.Float64())
if !s.TotalQuantity.IsZero() { s.placeLayerOrder(ctx, s.LastLow, limitPrice, price, orderExecutor)
q = s.TotalQuantity.Div(s.Entry.NumLayers)
} }
})
session.MarketDataStream.OnKLineClosed(func(kline types.KLine) { session.MarketDataStream.OnKLineClosed(func(kline types.KLine) {
if kline.Symbol != s.Symbol || kline.Interval != s.Interval { if kline.Symbol != s.Symbol || kline.Interval != s.Interval {
@ -239,9 +275,9 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
if s.pivot.LastLow() > 0. { if s.pivot.LastLow() > 0. {
log.Infof("pivot low signal detected: %f %s", s.pivot.LastLow(), kline.EndTime.Time()) log.Infof("pivot low signal detected: %f %s", s.pivot.LastLow(), kline.EndTime.Time())
lastLow = fixedpoint.NewFromFloat(s.pivot.LastLow()) s.LastLow = fixedpoint.NewFromFloat(s.pivot.LastLow())
} else { } else {
if canClosePosition(s.Position, lastLow, kline.Close) { if canClosePosition(s.Position, s.LastLow, kline.Close) {
R := kline.Close.Div(s.Position.AverageCost) R := kline.Close.Div(s.Position.AverageCost)
if R.Compare(fixedpoint.One.Add(s.Exit.StopLossPercentage)) > 0 { if R.Compare(fixedpoint.One.Add(s.Exit.StopLossPercentage)) > 0 {
// SL // SL
@ -259,12 +295,12 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
s.tradeCollector.Process() s.tradeCollector.Process()
} }
} }
lastLow = fixedpoint.Zero s.LastLow = fixedpoint.Zero
} }
if !lastLow.IsZero() { if !s.LastLow.IsZero() {
s.pivotBuffer = append(s.pivotBuffer, lastLow) s.pivotBuffer = append(s.pivotBuffer, s.LastLow)
if err := s.activeMakerOrders.GracefulCancel(ctx, s.session.Exchange); err != nil { if err := s.activeMakerOrders.GracefulCancel(ctx, s.session.Exchange); err != nil {
log.WithError(err).Errorf("graceful cancel order error") log.WithError(err).Errorf("graceful cancel order error")
@ -272,35 +308,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
limitPrice := s.getValidPivotLow(kline.Close) limitPrice := s.getValidPivotLow(kline.Close)
log.Infof("place limit sell start from %f adds up to %f percent with %f layers of orders", limitPrice.Float64(), s.Entry.CatBounceRatio.Mul(fixedpoint.NewFromInt(100)).Float64(), s.Entry.NumLayers.Float64()) log.Infof("place limit sell start from %f adds up to %f percent with %f layers of orders", limitPrice.Float64(), s.Entry.CatBounceRatio.Mul(fixedpoint.NewFromInt(100)).Float64(), s.Entry.NumLayers.Float64())
s.placeLayerOrder(ctx, s.LastLow, limitPrice, kline.Close, orderExecutor)
for i := 0; i < int(s.Entry.NumLayers.Float64()); i++ {
balances := s.session.GetAccount().Balances()
quoteBalance, _ := balances[s.Market.QuoteCurrency]
baseBalance, _ := balances[s.Market.BaseCurrency]
p := limitPrice.Mul(fixedpoint.One.Add(s.Entry.CatBounceRatio.Sub(fixedpoint.NewFromFloat(d.Float64() * float64(i)))))
if futuresMode {
//log.Infof("futures mode on")
if q.Mul(p).Compare(quoteBalance.Available) <= 0 {
s.placeOrder(ctx, lastLow, p, kline.Close, q, orderExecutor)
s.tradeCollector.Process()
}
} else if s.Environment.IsBackTesting() {
//log.Infof("spot backtest mode on")
if q.Compare(baseBalance.Available) <= 0 {
s.placeOrder(ctx, lastLow, p, kline.Close, q, orderExecutor)
s.tradeCollector.Process()
}
} else {
//log.Infof("spot mode on")
if q.Compare(baseBalance.Available) <= 0 {
s.placeOrder(ctx, lastLow, p, kline.Close, q, orderExecutor)
s.tradeCollector.Process()
}
}
}
//s.placeOrder(ctx, lastLow.Mul(fixedpoint.One.Add(s.CatBounceRatio)), s.Quantity, orderExecutor) //s.placeOrder(ctx, lastLow.Mul(fixedpoint.One.Add(s.CatBounceRatio)), s.Quantity, orderExecutor)
} }
}) })