mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-22 23:05:15 +00:00
bbgo: add ClosedKLineStop trigger
This commit is contained in:
parent
f323e91a56
commit
7438798390
|
@ -72,7 +72,9 @@ func (s *CumulatedVolumeTakeProfit) Bind(session *ExchangeSession, orderExecutor
|
||||||
cqv.Float64(),
|
cqv.Float64(),
|
||||||
s.MinQuoteVolume.Float64(), kline.Close.Float64())
|
s.MinQuoteVolume.Float64(), kline.Close.Float64())
|
||||||
|
|
||||||
_ = orderExecutor.ClosePosition(context.Background(), fixedpoint.One, "cumulatedVolumeTakeProfit")
|
if err := orderExecutor.ClosePosition(context.Background(), fixedpoint.One, "cumulatedVolumeTakeProfit") ; err != nil {
|
||||||
|
log.WithError(err).Errorf("close position error")
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -19,6 +19,10 @@ type TrendEMA struct {
|
||||||
types.IntervalWindow
|
types.IntervalWindow
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ClosedKLineStop struct {
|
||||||
|
types.IntervalWindow
|
||||||
|
}
|
||||||
|
|
||||||
// BreakLow -- when price breaks the previous pivot low, we set a trade entry
|
// BreakLow -- when price breaks the previous pivot low, we set a trade entry
|
||||||
type BreakLow struct {
|
type BreakLow struct {
|
||||||
Symbol string
|
Symbol string
|
||||||
|
@ -42,7 +46,13 @@ type BreakLow struct {
|
||||||
|
|
||||||
TrendEMA *TrendEMA `json:"trendEMA"`
|
TrendEMA *TrendEMA `json:"trendEMA"`
|
||||||
|
|
||||||
|
ClosedKLineStop *ClosedKLineStop `json:"closedKLineStop"`
|
||||||
|
|
||||||
lastLow fixedpoint.Value
|
lastLow fixedpoint.Value
|
||||||
|
|
||||||
|
// lastBreakLow is the low that the price just break
|
||||||
|
lastBreakLow fixedpoint.Value
|
||||||
|
|
||||||
pivotLow *indicator.PivotLow
|
pivotLow *indicator.PivotLow
|
||||||
pivotLowPrices []fixedpoint.Value
|
pivotLowPrices []fixedpoint.Value
|
||||||
|
|
||||||
|
@ -66,6 +76,10 @@ func (s *BreakLow) Subscribe(session *bbgo.ExchangeSession) {
|
||||||
if s.TrendEMA != nil {
|
if s.TrendEMA != nil {
|
||||||
session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.TrendEMA.Interval})
|
session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.TrendEMA.Interval})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.ClosedKLineStop != nil {
|
||||||
|
session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.ClosedKLineStop.Interval})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *BreakLow) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.GeneralOrderExecutor) {
|
func (s *BreakLow) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.GeneralOrderExecutor) {
|
||||||
|
@ -113,7 +127,34 @@ func (s *BreakLow) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.Gener
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
session.MarketDataStream.OnKLineClosed(types.KLineWith(symbol, types.Interval1m, func(kline types.KLine) {
|
if s.ClosedKLineStop != nil {
|
||||||
|
// if the position is already opened, and we just break the low, this checks if the kline closed above the low,
|
||||||
|
// so that we can close the position earlier
|
||||||
|
session.MarketDataStream.OnKLineClosed(types.KLineWith(s.Symbol, s.ClosedKLineStop.Interval, func(k types.KLine) {
|
||||||
|
// make sure the position is opened, and it's a short position
|
||||||
|
if !position.IsOpened(k.Close) || !position.IsShort() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure we recorded the last break low
|
||||||
|
if s.lastBreakLow.IsZero() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// the kline opened below the last break low, and closed above the last break low
|
||||||
|
if k.Open.Compare(s.lastBreakLow) < 0 && k.Close.Compare(s.lastBreakLow) > 0 {
|
||||||
|
bbgo.Notify("kLine closed above the last break low, triggering stop earlier")
|
||||||
|
if err := s.orderExecutor.ClosePosition(context.Background(), one, "kLineClosedStop"); err != nil {
|
||||||
|
log.WithError(err).Error("position close error")
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset to zero
|
||||||
|
s.lastBreakLow = fixedpoint.Zero
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
session.MarketDataStream.OnKLineClosed(types.KLineWith(s.Symbol, types.Interval1m, func(kline types.KLine) {
|
||||||
if len(s.pivotLowPrices) == 0 {
|
if len(s.pivotLowPrices) == 0 {
|
||||||
log.Infof("currently there is no pivot low prices, can not check break low...")
|
log.Infof("currently there is no pivot low prices, can not check break low...")
|
||||||
return
|
return
|
||||||
|
@ -146,6 +187,10 @@ func (s *BreakLow) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.Gener
|
||||||
|
|
||||||
log.Infof("%s breakLow signal detected, closed price %f < breakPrice %f", kline.Symbol, closePrice.Float64(), breakPrice.Float64())
|
log.Infof("%s breakLow signal detected, closed price %f < breakPrice %f", kline.Symbol, closePrice.Float64(), breakPrice.Float64())
|
||||||
|
|
||||||
|
if s.lastBreakLow.IsZero() || previousLow.Compare(s.lastBreakLow) < 0 {
|
||||||
|
s.lastBreakLow = previousLow
|
||||||
|
}
|
||||||
|
|
||||||
if position.IsOpened(kline.Close) {
|
if position.IsOpened(kline.Close) {
|
||||||
log.Infof("position is already opened, skip short")
|
log.Infof("position is already opened, skip short")
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in New Issue
Block a user