diff --git a/config/ewo_dgtrd.yaml b/config/ewo_dgtrd.yaml new file mode 100644 index 000000000..d87f52b2f --- /dev/null +++ b/config/ewo_dgtrd.yaml @@ -0,0 +1,26 @@ +--- +sessions: + binance: + exchange: binance + envVarPrefix: binance + +exchangeStrategies: + +- on: binance + ewo_dgtrd: + symbol: BNBBUSD + interval: 1h + threshold: 13 + useEma: true + sigWin: 5 + +backtest: + startTime: "2022-04-06" + endTime: "2022-04-07" + symbols: + - BNBBUSD + account: + binance: + balances: + BNB: 0 + BUSD: 10000 diff --git a/pkg/cmd/builtin.go b/pkg/cmd/builtin.go index d97bd1b17..68d2e27c2 100644 --- a/pkg/cmd/builtin.go +++ b/pkg/cmd/builtin.go @@ -23,4 +23,5 @@ import ( _ "github.com/c9s/bbgo/pkg/strategy/xmaker" _ "github.com/c9s/bbgo/pkg/strategy/xnav" _ "github.com/c9s/bbgo/pkg/strategy/xpuremaker" + _ "github.com/c9s/bbgo/pkg/strategy/ewo_dgtrd" ) diff --git a/pkg/strategy/ewo_dgtrd/2 b/pkg/strategy/ewo_dgtrd/2 deleted file mode 100644 index 85cee29d9..000000000 --- a/pkg/strategy/ewo_dgtrd/2 +++ /dev/null @@ -1,103 +0,0 @@ -package ewo_dgtrd - -import ( - "context" - - "github.com/sirupsen/logrus" - - "github.com/c9s/bbgo/pkg/bbgo" - "github.com/c9s/bbgo/pkg/fixedpoint" - "github.com/c9s/bbgo/pkg/types" -) - -const ID = "ewo_dgtrd" - -var log = logrus.WithField("strategy", ID) - -func init() { - bbgo.RegisterStrategy(ID, &Strategy{}) -} - -type Strategy struct { - Symbol string `json:"symbol"` - Interval types.Interval `json:"interval"` - Threshold float64 `json:"threshold"` // strength threshold - UseEma bool `json:"useEma"` // use exponential ma or simple ma - SignalWindow int `json:"sigWin"` // signal window -} - -func (s *Strategy) ID() string { - return ID -} - -func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) { - log.Infof("subscribe %s", s.Symbol) - session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval.String()}) -} - -type EwoSignal interface { - types.Series - Update(value float64) -} - -func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession) error { - store, ok := session.MarketDataStore(s.Symbol) - if !ok { - log.Errorf("cannot find symbol %s", s.Symbol) - return - } - klineWindow, ok := store.KLinesOfInterval(s.Interval) - if !ok { - log.Errorf("cannot find kline window of %v", s.Interval) - return - } - indicatorSet, ok := session.StandardIndicatorSet(s.Symbol) - if !ok { - log.Errorf("cannot get indicatorSet of %s", s.Symbol) - return - } - var ma5, ma34 Series - if s.UseEma { - ma5 = indicatorSet.EWMA(types.IntervalWindow{s.Interval, 5}) - ma34 = indicatorSet.EWMA(types.IntervalWindow{s.Interval, 34}) - } else { - ma5 = indicatorSet.SMA(types.IntervalWindow{s.Interval, 5}) - ma34 = indicatorSet.SMA(types.IntervalWindow{s.Interval, 34}) - } - var ewoSignal EwoSignal - if s.UseEma { - ewoSignal := &indicator.EWMA{types.IntervalWindow{s.Interval, s.SignalWindow}} - } else { - ewoSignal := &indicator.SMA{types.IntervalWindow{s.Interval, s.SignalWindow}} - } - for _, kline := range klineWindow { - ewoSignal.Update(kline) - } - session.MarketDataStream.OnKLineClosed(func(kline types.KLine) { - var ewo - if kline.Symbol != s.Symbol { - return - } - ewo = types.Mul(types.Minus(types.Div(ma5, ma34), 1.0), 100.) - ewoSignal.Update(ewo.Last()) - - if s.UseEma { - ewoSignal = indicator.EWMA(ewo, s.SignalWindow) - } else { - ewoSignal = sma(ewo, s.SignalWindow) - } - - if CrossOver(ewo, ewoSignal).Last() { - if ewo.Last() < -s.Threshold { - // strong long - } else { - // Long - } - } else if CrossUnder(ewo, ewoSignal).Last() { - if ewo.Last() > s.Threshold { - // Strong short - } else { - // short - } - } -} diff --git a/pkg/strategy/ewo_dgtrd/strategy.go b/pkg/strategy/ewo_dgtrd/strategy.go index 0f8cca74a..37837f3ca 100644 --- a/pkg/strategy/ewo_dgtrd/strategy.go +++ b/pkg/strategy/ewo_dgtrd/strategy.go @@ -46,6 +46,16 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se log.Errorf("cannot get indicatorSet of %s", s.Symbol) return nil } + store, ok := session.MarketDataStore(s.Symbol) + if !ok { + log.Errorf("cannot get marketdatastore of %s", s.Symbol) + return nil + } + window, ok := store.KLinesOfInterval(s.Interval) + if !ok { + log.Errorf("cannot get klinewindow of %s", s.Interval) + } + mid := types.Div(types.Add(window.Open(), window.Close()), 2) var ma5, ma34, ewo types.Series if s.UseEma { ma5 = indicatorSet.EWMA(types.IntervalWindow{s.Interval, 5}) @@ -62,7 +72,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se ewoSignal = &indicator.SMA{IntervalWindow: types.IntervalWindow{s.Interval, s.SignalWindow}} } session.MarketDataStream.OnKLineClosed(func(kline types.KLine) { - if kline.Symbol != s.Symbol { + if kline.Symbol != s.Symbol || kline.Interval != s.Interval { return } if ewoSignal.Length() == 0 { @@ -80,21 +90,27 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se return } - if types.CrossOver(ewo, ewoSignal).Last() { + longSignal := types.CrossOver(ewo, ewoSignal) + shortSignal := types.CrossUnder(ewo, ewoSignal) + nextVal := types.Predict(mid, 5, 1) + IsBull := mid.Last() < nextVal + log.Warnf("mid %v, last %v, next %v", kline.Mid(), mid.Last(), nextVal) + + if longSignal.Last() && IsBull { if ewo.Last() < -s.Threshold { // strong long - log.Infof("strong long at %v", lastPrice) + log.Infof("strong long at %v, timestamp: %s", lastPrice, kline.StartTime) } else { - log.Infof("long at %v", lastPrice) + log.Infof("long at %v, timestamp: %s", lastPrice, kline.StartTime) // Long } - } else if types.CrossUnder(ewo, ewoSignal).Last() { + } else if shortSignal.Last() && !IsBull { if ewo.Last() > s.Threshold { // Strong short - log.Infof("strong short at %v", lastPrice) + log.Infof("strong short at %v, timestamp: %s", lastPrice, kline.StartTime) } else { // short - log.Infof("short at %v", lastPrice) + log.Infof("short at %v, timestamp: %s", lastPrice, kline.StartTime) } } })