mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
bollmaker: add ema cross signal to bollmaker strategy
This commit is contained in:
parent
6a07af80d8
commit
46329c3a24
|
@ -17,7 +17,7 @@ backtest:
|
||||||
# see here for more details
|
# see here for more details
|
||||||
# https://www.investopedia.com/terms/m/maximum-drawdown-mdd.asp
|
# https://www.investopedia.com/terms/m/maximum-drawdown-mdd.asp
|
||||||
startTime: "2022-05-01"
|
startTime: "2022-05-01"
|
||||||
endTime: "2022-08-14"
|
endTime: "2023-11-01"
|
||||||
sessions:
|
sessions:
|
||||||
- binance
|
- binance
|
||||||
symbols:
|
symbols:
|
||||||
|
@ -200,6 +200,12 @@ exchangeStrategies:
|
||||||
# buyBelowNeutralSMA: when this set, it will only place buy order when the current price is below the SMA line.
|
# buyBelowNeutralSMA: when this set, it will only place buy order when the current price is below the SMA line.
|
||||||
buyBelowNeutralSMA: true
|
buyBelowNeutralSMA: true
|
||||||
|
|
||||||
|
emaCross:
|
||||||
|
enabled: true
|
||||||
|
interval: 1h
|
||||||
|
fastWindow: 3
|
||||||
|
slowWindow: 12
|
||||||
|
|
||||||
exits:
|
exits:
|
||||||
|
|
||||||
# roiTakeProfit is used to force taking profit by percentage of the position ROI (currently the price change)
|
# roiTakeProfit is used to force taking profit by percentage of the position ROI (currently the price change)
|
||||||
|
|
|
@ -46,9 +46,13 @@ type BollingerSetting struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type EMACrossSetting struct {
|
type EMACrossSetting struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
Interval types.Interval `json:"interval"`
|
Interval types.Interval `json:"interval"`
|
||||||
FastWindow int `json:"fastWindow"`
|
FastWindow int `json:"fastWindow"`
|
||||||
SlowWindow int `json:"slowWindow"`
|
SlowWindow int `json:"slowWindow"`
|
||||||
|
|
||||||
|
fastEMA, slowEMA *indicatorv2.EWMAStream
|
||||||
|
cross *indicatorv2.CrossStream
|
||||||
}
|
}
|
||||||
|
|
||||||
type Strategy struct {
|
type Strategy struct {
|
||||||
|
@ -174,6 +178,8 @@ type Strategy struct {
|
||||||
// neutralBoll is the neutral price section
|
// neutralBoll is the neutral price section
|
||||||
neutralBoll *indicatorv2.BOLLStream
|
neutralBoll *indicatorv2.BOLLStream
|
||||||
|
|
||||||
|
shouldBuy bool
|
||||||
|
|
||||||
// StrategyController
|
// StrategyController
|
||||||
bbgo.StrategyController
|
bbgo.StrategyController
|
||||||
}
|
}
|
||||||
|
@ -280,6 +286,7 @@ func (s *Strategy) placeOrders(ctx context.Context, midPrice fixedpoint.Value, k
|
||||||
Price: askPrice,
|
Price: askPrice,
|
||||||
Market: s.Market,
|
Market: s.Market,
|
||||||
}
|
}
|
||||||
|
|
||||||
buyOrder := types.SubmitOrder{
|
buyOrder := types.SubmitOrder{
|
||||||
Symbol: s.Symbol,
|
Symbol: s.Symbol,
|
||||||
Side: types.SideTypeBuy,
|
Side: types.SideTypeBuy,
|
||||||
|
@ -438,14 +445,20 @@ func (s *Strategy) placeOrders(ctx context.Context, midPrice fixedpoint.Value, k
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !s.shouldBuy {
|
||||||
|
log.Infof("shouldBuy is turned off, skip placing buy order")
|
||||||
|
canBuy = false
|
||||||
|
}
|
||||||
|
|
||||||
if canSell {
|
if canSell {
|
||||||
submitOrders = append(submitOrders, sellOrder)
|
submitOrders = append(submitOrders, sellOrder)
|
||||||
}
|
}
|
||||||
|
|
||||||
if canBuy {
|
if canBuy {
|
||||||
submitOrders = append(submitOrders, buyOrder)
|
submitOrders = append(submitOrders, buyOrder)
|
||||||
}
|
}
|
||||||
|
|
||||||
// condition for lower the average cost
|
// condition for lowering the average cost
|
||||||
/*
|
/*
|
||||||
if midPrice < s.Position.AverageCost.MulFloat64(1.0-s.MinProfitSpread.Float64()) && canBuy {
|
if midPrice < s.Position.AverageCost.MulFloat64(1.0-s.MinProfitSpread.Float64()) && canBuy {
|
||||||
submitOrders = append(submitOrders, buyOrder)
|
submitOrders = append(submitOrders, buyOrder)
|
||||||
|
@ -481,9 +494,26 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
|
||||||
// StrategyController
|
// StrategyController
|
||||||
s.Status = types.StrategyStatusRunning
|
s.Status = types.StrategyStatusRunning
|
||||||
|
|
||||||
|
s.shouldBuy = true
|
||||||
s.neutralBoll = session.Indicators(s.Symbol).BOLL(s.NeutralBollinger.IntervalWindow, s.NeutralBollinger.BandWidth)
|
s.neutralBoll = session.Indicators(s.Symbol).BOLL(s.NeutralBollinger.IntervalWindow, s.NeutralBollinger.BandWidth)
|
||||||
s.defaultBoll = session.Indicators(s.Symbol).BOLL(s.DefaultBollinger.IntervalWindow, s.DefaultBollinger.BandWidth)
|
s.defaultBoll = session.Indicators(s.Symbol).BOLL(s.DefaultBollinger.IntervalWindow, s.DefaultBollinger.BandWidth)
|
||||||
|
|
||||||
|
if s.EMACrossSetting != nil && s.EMACrossSetting.Enabled {
|
||||||
|
s.EMACrossSetting.fastEMA = session.Indicators(s.Symbol).EWMA(types.IntervalWindow{Interval: s.Interval, Window: s.EMACrossSetting.FastWindow})
|
||||||
|
s.EMACrossSetting.slowEMA = session.Indicators(s.Symbol).EWMA(types.IntervalWindow{Interval: s.Interval, Window: s.EMACrossSetting.SlowWindow})
|
||||||
|
s.EMACrossSetting.cross = indicatorv2.Cross(s.EMACrossSetting.fastEMA, s.EMACrossSetting.slowEMA)
|
||||||
|
s.EMACrossSetting.cross.OnUpdate(func(v float64) {
|
||||||
|
switch indicatorv2.CrossType(v) {
|
||||||
|
case indicatorv2.CrossOver:
|
||||||
|
s.shouldBuy = true
|
||||||
|
case indicatorv2.CrossUnder:
|
||||||
|
s.shouldBuy = false
|
||||||
|
// TODO: can partially close position when necessary
|
||||||
|
// s.orderExecutor.ClosePosition(ctx)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Setup dynamic spread
|
// Setup dynamic spread
|
||||||
if s.DynamicSpread.IsEnabled() {
|
if s.DynamicSpread.IsEnabled() {
|
||||||
if s.DynamicSpread.Interval == "" {
|
if s.DynamicSpread.Interval == "" {
|
||||||
|
@ -565,7 +595,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
|
||||||
})
|
})
|
||||||
|
|
||||||
session.UserDataStream.OnStart(func() {
|
session.UserDataStream.OnStart(func() {
|
||||||
if s.UseTickerPrice {
|
if !bbgo.IsBackTesting && s.UseTickerPrice {
|
||||||
ticker, err := s.session.Exchange.QueryTicker(ctx, s.Symbol)
|
ticker, err := s.session.Exchange.QueryTicker(ctx, s.Symbol)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in New Issue
Block a user