Skip to content

Commit

Permalink
fix ewma calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
c9s committed Nov 21, 2021
1 parent 20f0e8d commit 513a799
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 16 deletions.
3 changes: 3 additions & 0 deletions pkg/bbgo/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ var (
)

func init() {
// when using --dotenv option, the dotenv is loaded from command.PersistentPreRunE, not init.
// hence here the env var won't enable the debug flag
util.SetEnvVarBool("DEBUG_EWMA", &debugEWMA)
util.SetEnvVarBool("DEBUG_SMA", &debugSMA)
}
Expand Down Expand Up @@ -411,6 +413,7 @@ func (session *ExchangeSession) initSymbol(ctx context.Context, environ *Environ
// always subscribe the 1m kline so we can make sure the connection persists.
klineSubscriptions[types.Interval1m] = struct{}{}

// Aggregate the intervals that we are using in the subscriptions.
for _, sub := range session.Subscriptions {
switch sub.Channel {
case types.BookChannel:
Expand Down
3 changes: 2 additions & 1 deletion pkg/cmd/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import (
_ "github.com/c9s/bbgo/pkg/strategy/flashcrash"
_ "github.com/c9s/bbgo/pkg/strategy/gap"
_ "github.com/c9s/bbgo/pkg/strategy/grid"
_ "github.com/c9s/bbgo/pkg/strategy/kline"
_ "github.com/c9s/bbgo/pkg/strategy/pricealert"
_ "github.com/c9s/bbgo/pkg/strategy/pricedrop"
_ "github.com/c9s/bbgo/pkg/strategy/schedule"
_ "github.com/c9s/bbgo/pkg/strategy/support"
_ "github.com/c9s/bbgo/pkg/strategy/swing"
_ "github.com/c9s/bbgo/pkg/strategy/techsignal"
_ "github.com/c9s/bbgo/pkg/strategy/xbalance"
_ "github.com/c9s/bbgo/pkg/strategy/xnav"
_ "github.com/c9s/bbgo/pkg/strategy/xmaker"
_ "github.com/c9s/bbgo/pkg/strategy/xnav"
_ "github.com/c9s/bbgo/pkg/strategy/xpuremaker"
)
6 changes: 3 additions & 3 deletions pkg/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,7 @@ func init() {
RootCmd.PersistentFlags().String("ftx-api-key", "", "ftx api key")
RootCmd.PersistentFlags().String("ftx-api-secret", "", "ftx api secret")
RootCmd.PersistentFlags().String("ftx-subaccount", "", "subaccount name. Specify it if the credential is for subaccount.")
}

func Execute() {
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))

// Enable environment variable binding, the env vars are not overloaded yet.
Expand All @@ -129,7 +127,6 @@ func Execute() {
log.WithError(err).Fatal("failed to load config file")
}
*/

// Once the flags are defined, we can bind config keys with flags.
if err := viper.BindPFlags(RootCmd.PersistentFlags()); err != nil {
log.WithError(err).Errorf("failed to bind persistent flags. please check the flag settings.")
Expand All @@ -140,6 +137,9 @@ func Execute() {
log.WithError(err).Errorf("failed to bind local flags. please check the flag settings.")
return
}
}

func Execute() {

log.SetFormatter(&prefixed.TextFormatter{})

Expand Down
22 changes: 11 additions & 11 deletions pkg/indicator/ewma.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (inc *EWMA) Update(value float64) {
inc.Values.Push(value)
return
} else if len(inc.Values) > MaxNumOfEWMA {
inc.Values = inc.Values[MaxNumOfEWMATruncateSize - 1:]
inc.Values = inc.Values[MaxNumOfEWMATruncateSize-1:]
}

ema := (1-multiplier)*inc.Last() + multiplier*value
Expand All @@ -54,31 +54,30 @@ func (inc *EWMA) calculateAndUpdate(allKLines []types.KLine) {
var dataLen = len(allKLines)
var multiplier = 2.0 / (float64(inc.Window) + 1)

// init the values from the kline data
var from = 1
// init the values fromNthK the kline data
var fromNthK = 1
if len(inc.Values) == 0 {
// for the first value, we should use the close price
inc.Values = []float64{priceF(allKLines[0])}
} else {
// from = len(inc.Values)
fromNthK = len(inc.Values)

// update ewma with the existing values
for i := dataLen - 1; i > 0; i-- {
var k = allKLines[i]
if k.StartTime.After(inc.LastOpenTime) {
from = i
fromNthK = i
} else {
break
}
}
}

if len(inc.Values) >= MaxNumOfEWMA {
TruncateSize := MaxNumOfEWMATruncateSize
inc.Values = inc.Values[TruncateSize:]
}
if len(inc.Values) >= MaxNumOfEWMA {
inc.Values = inc.Values[MaxNumOfEWMATruncateSize-1:]
}

for i := from; i < dataLen; i++ {
for i := fromNthK; i < dataLen; i++ {
var k = allKLines[i]
var ewma = priceF(k)*multiplier + (1-multiplier)*inc.Values[i-1]
inc.Values.Push(ewma)
Expand All @@ -87,7 +86,8 @@ func (inc *EWMA) calculateAndUpdate(allKLines []types.KLine) {
}

if len(inc.Values) != dataLen {
log.Warnf("%s EMA (%d) value length (%d) != all kline data length (%d)", inc.Interval, inc.Window, len(inc.Values), dataLen)
// check error
log.Warnf("%s EMA (%d) value length (%d) != kline window length (%d)", inc.Interval, inc.Window, len(inc.Values), dataLen)
}

v1 := math.Floor(inc.Values[len(inc.Values)-1]*100.0) / 100.0
Expand Down
2 changes: 1 addition & 1 deletion pkg/indicator/sma.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (inc *SMA) calculateAndUpdate(kLines []types.KLine) {
inc.Values.Push(sma)

if len(inc.Values) > MaxNumOfSMA {
inc.Values = inc.Values[MaxNumOfSMATruncateSize - 1:]
inc.Values = inc.Values[MaxNumOfSMATruncateSize-1:]
}

inc.EndTime = kLines[index].EndTime
Expand Down
42 changes: 42 additions & 0 deletions pkg/strategy/kline/strategy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package kline

import (
"context"
"github.com/sirupsen/logrus"

"github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/types"
)

const ID = "kline"

var log = logrus.WithField("strategy", ID)

func init() {
bbgo.RegisterStrategy(ID, &Strategy{})
}

type Strategy struct {
Symbol string `json:"symbol"`
MovingAverage types.IntervalWindow `json:"movingAverage"`
}

func (s *Strategy) ID() string {
return ID
}

func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) {
session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: string(s.MovingAverage.Interval)})
}

func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession) error {
session.MarketDataStream.OnKLineClosed(func(kline types.KLine) {
// skip k-lines from other symbols
if kline.Symbol != s.Symbol {
return
}

log.Infof("%s", kline.String())
})
return nil
}

0 comments on commit 513a799

Please sign in to comment.