diff --git a/pkg/backtest/report.go b/pkg/backtest/report.go index 7cae8335a..0e1574280 100644 --- a/pkg/backtest/report.go +++ b/pkg/backtest/report.go @@ -35,6 +35,7 @@ type SummaryReport struct { EndTime time.Time `json:"endTime"` Sessions []string `json:"sessions"` Symbols []string `json:"symbols"` + Intervals []types.Interval `json:"intervals"` InitialTotalBalances types.BalanceMap `json:"initialTotalBalances"` FinalTotalBalances types.BalanceMap `json:"finalTotalBalances"` @@ -48,6 +49,8 @@ type SummaryReport struct { type SessionSymbolReport struct { Exchange types.ExchangeName `json:"exchange"` Symbol string `json:"symbol,omitempty"` + Intervals []types.Interval `json:"intervals,omitempty"` + Subscriptions []types.Subscription `json:"subscriptions"` Market types.Market `json:"market"` LastPrice fixedpoint.Value `json:"lastPrice,omitempty"` StartPrice fixedpoint.Value `json:"startPrice,omitempty"` diff --git a/pkg/bbgo/smart_stops.go b/pkg/bbgo/smart_stops.go index e3dd0ca26..7a17e1e38 100644 --- a/pkg/bbgo/smart_stops.go +++ b/pkg/bbgo/smart_stops.go @@ -52,7 +52,7 @@ func NewTrailingStopController(symbol string, config *TrailingStop) *TrailingSto func (c *TrailingStopController) Subscribe(session *ExchangeSession) { session.Subscribe(types.KLineChannel, c.Symbol, types.SubscribeOptions{ - Interval: c.Interval.String(), + Interval: c.Interval, }) } diff --git a/pkg/cmd/backtest.go b/pkg/cmd/backtest.go index 400f9fcbe..77ee77088 100644 --- a/pkg/cmd/backtest.go +++ b/pkg/cmd/backtest.go @@ -273,7 +273,8 @@ var BacktestCmd = &cobra.Command{ return err } - exchangeSources, err := toExchangeSources(environ.Sessions()) + backTestIntervals := []types.Interval{types.Interval1h, types.Interval1d} + exchangeSources, err := toExchangeSources(environ.Sessions(), backTestIntervals...) if err != nil { return err } @@ -468,7 +469,21 @@ var BacktestCmd = &cobra.Command{ Symbols: nil, } + allKLineIntervals := map[types.Interval]struct{}{} for _, session := range environ.Sessions() { + for _, sub := range session.Subscriptions { + if sub.Channel == types.KLineChannel { + allKLineIntervals[types.Interval(sub.Options.Interval)] = struct{}{} + } + } + } + + for interval := range allKLineIntervals { + summaryReport.Intervals = append(summaryReport.Intervals, interval) + } + + for _, session := range environ.Sessions() { + for symbol, trades := range session.Trades { symbolReport, err := createSymbolReport(userConfig, session, symbol, trades.Trades) if err != nil { @@ -551,6 +566,22 @@ func createSymbolReport(userConfig *bbgo.Config, session *bbgo.ExchangeSession, FinalBalances: finalBalances, // Manifests: manifests, } + + for _, s := range session.Subscriptions { + symbolReport.Subscriptions = append(symbolReport.Subscriptions, s) + } + + sessionKLineIntervals := map[types.Interval]struct{}{} + for _, sub := range session.Subscriptions { + if sub.Channel == types.KLineChannel { + sessionKLineIntervals[types.Interval(sub.Options.Interval)] = struct{}{} + } + } + + for interval := range sessionKLineIntervals { + symbolReport.Intervals = append(symbolReport.Intervals, interval) + } + return &symbolReport, nil } @@ -586,12 +617,12 @@ func confirmation(s string) bool { } } -func toExchangeSources(sessions map[string]*bbgo.ExchangeSession) (exchangeSources []backtest.ExchangeDataSource, err error) { +func toExchangeSources(sessions map[string]*bbgo.ExchangeSession, extraIntervals ...types.Interval) (exchangeSources []backtest.ExchangeDataSource, err error) { for _, session := range sessions { exchange := session.Exchange.(*backtest.Exchange) exchange.InitMarketData() - c, err := exchange.SubscribeMarketData(types.Interval1h, types.Interval1d) + c, err := exchange.SubscribeMarketData(extraIntervals...) if err != nil { return exchangeSources, err } diff --git a/pkg/cmd/kline.go b/pkg/cmd/kline.go index ccdeb7c89..7a346d0a3 100644 --- a/pkg/cmd/kline.go +++ b/pkg/cmd/kline.go @@ -56,7 +56,7 @@ var klineCmd = &cobra.Command{ s := session.Exchange.NewStream() s.SetPublicOnly() - s.Subscribe(types.KLineChannel, symbol, types.SubscribeOptions{Interval: interval}) + s.Subscribe(types.KLineChannel, symbol, types.SubscribeOptions{Interval: types.Interval(interval)}) s.OnKLineClosed(func(kline types.KLine) { log.Infof("kline closed: %s", kline.String()) diff --git a/pkg/exchange/max/stream.go b/pkg/exchange/max/stream.go index 385e24b04..d6d1e646c 100644 --- a/pkg/exchange/max/stream.go +++ b/pkg/exchange/max/stream.go @@ -92,7 +92,7 @@ func (s *Stream) handleConnect() { Channel: string(sub.Channel), Market: toLocalSymbol(sub.Symbol), Depth: depth, - Resolution: sub.Options.Interval, + Resolution: sub.Options.Interval.String(), }) } diff --git a/pkg/exchange/okex/convert.go b/pkg/exchange/okex/convert.go index cb8a94f4a..fa70a1352 100644 --- a/pkg/exchange/okex/convert.go +++ b/pkg/exchange/okex/convert.go @@ -17,7 +17,7 @@ func toGlobalSymbol(symbol string) string { return strings.ReplaceAll(symbol, "-", "") } -////go:generate sh -c "echo \"package okex\nvar spotSymbolMap = map[string]string{\n\" $(curl -s -L 'https://okex.com/api/v5/public/instruments?instType=SPOT' | jq -r '.data[] | \"\\(.instId | sub(\"-\" ; \"\") | tojson ): \\( .instId | tojson),\n\"') \"\n}\" > symbols.go" +// //go:generate sh -c "echo \"package okex\nvar spotSymbolMap = map[string]string{\n\" $(curl -s -L 'https://okex.com/api/v5/public/instruments?instType=SPOT' | jq -r '.data[] | \"\\(.instId | sub(\"-\" ; \"\") | tojson ): \\( .instId | tojson),\n\"') \"\n}\" > symbols.go" //go:generate go run gensymbols.go func toLocalSymbol(symbol string) string { if s, ok := spotSymbolMap[symbol]; ok { @@ -68,18 +68,19 @@ var CandleChannels = []string{ "candle30m", "candle15m", "candle5m", "candle3m", "candle1m", } -func convertIntervalToCandle(interval string) string { - switch interval { +func convertIntervalToCandle(interval types.Interval) string { + s := interval.String() + switch s { case "1h", "2h", "4h", "6h", "12h", "1d", "3d": - return "candle" + strings.ToUpper(interval) + return "candle" + strings.ToUpper(s) case "1m", "5m", "15m", "30m": - return "candle" + interval + return "candle" + s } - return "candle" + interval + return "candle" + s } func convertSubscription(s types.Subscription) (WebsocketSubscription, error) { @@ -270,7 +271,7 @@ func toGlobalOrderType(orderType okexapi.OrderType) (types.OrderType, error) { return "", fmt.Errorf("unknown or unsupported okex order type: %s", orderType) } -func toLocalInterval(src string, ) string { +func toLocalInterval(src string) string { var re = regexp.MustCompile("\\d+[hdw]") return re.ReplaceAllStringFunc(src, func(w string) string { return strings.ToUpper(w) diff --git a/pkg/grpc/convert.go b/pkg/grpc/convert.go index cce9e77cc..e8354cf1d 100644 --- a/pkg/grpc/convert.go +++ b/pkg/grpc/convert.go @@ -34,7 +34,7 @@ func toSubscriptions(sub *pb.Subscription) (types.Subscription, error) { Symbol: sub.Symbol, Channel: types.KLineChannel, Options: types.SubscribeOptions{ - Interval: sub.Interval, + Interval: types.Interval(sub.Interval), }, }, nil } diff --git a/pkg/strategy/bollgrid/strategy.go b/pkg/strategy/bollgrid/strategy.go index f60440143..c657df16b 100644 --- a/pkg/strategy/bollgrid/strategy.go +++ b/pkg/strategy/bollgrid/strategy.go @@ -108,10 +108,10 @@ func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) { } // currently we need the 1m kline to update the last close price and indicators - session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval.String()}) + session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval}) if len(s.RepostInterval) > 0 && s.Interval != s.RepostInterval { - session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.RepostInterval.String()}) + session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.RepostInterval}) } } diff --git a/pkg/strategy/bollmaker/strategy.go b/pkg/strategy/bollmaker/strategy.go index be97db97a..f134ba107 100644 --- a/pkg/strategy/bollmaker/strategy.go +++ b/pkg/strategy/bollmaker/strategy.go @@ -185,18 +185,18 @@ func (s *Strategy) Initialize() error { func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) { session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{ - Interval: string(s.Interval), + Interval: s.Interval, }) if s.DefaultBollinger != nil && s.DefaultBollinger.Interval != "" { session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{ - Interval: string(s.DefaultBollinger.Interval), + Interval: s.DefaultBollinger.Interval, }) } if s.NeutralBollinger != nil && s.NeutralBollinger.Interval != "" { session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{ - Interval: string(s.NeutralBollinger.Interval), + Interval: s.NeutralBollinger.Interval, }) } diff --git a/pkg/strategy/emastop/strategy.go b/pkg/strategy/emastop/strategy.go index 222430713..396568c8e 100644 --- a/pkg/strategy/emastop/strategy.go +++ b/pkg/strategy/emastop/strategy.go @@ -73,8 +73,8 @@ func (s *Strategy) ID() string { } func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) { - session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval.String()}) - session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.MovingAverageInterval.String()}) + session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval}) + session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.MovingAverageInterval}) } func (s *Strategy) CrossSubscribe(sessions map[string]*bbgo.ExchangeSession) { @@ -83,7 +83,7 @@ func (s *Strategy) CrossSubscribe(sessions map[string]*bbgo.ExchangeSession) { // make sure we have the connection alive targetSession := sessions[s.TargetExchangeName] - targetSession.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval.String()}) + targetSession.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval}) } func (s *Strategy) clear(ctx context.Context, orderExecutor bbgo.OrderExecutor) { diff --git a/pkg/strategy/ewoDgtrd/strategy.go b/pkg/strategy/ewoDgtrd/strategy.go index 25d3a5888..4315e4fb0 100644 --- a/pkg/strategy/ewoDgtrd/strategy.go +++ b/pkg/strategy/ewoDgtrd/strategy.go @@ -81,8 +81,8 @@ func (s *Strategy) Initialize() error { func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) { log.Infof("subscribe %s", s.Symbol) - session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: types.Interval1m.String()}) - session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval.String()}) + session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: types.Interval1m}) + session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval}) session.Subscribe(types.BookTickerChannel, s.Symbol, types.SubscribeOptions{}) diff --git a/pkg/strategy/factorzoo/strategy.go b/pkg/strategy/factorzoo/strategy.go index acc67c5ac..2cf131fdf 100644 --- a/pkg/strategy/factorzoo/strategy.go +++ b/pkg/strategy/factorzoo/strategy.go @@ -3,11 +3,13 @@ package factorzoo import ( "context" "fmt" + + "github.com/sajari/regression" + "github.com/sirupsen/logrus" + "github.com/c9s/bbgo/pkg/bbgo" "github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/types" - "github.com/sajari/regression" - "github.com/sirupsen/logrus" ) const ID = "factorzoo" @@ -57,7 +59,7 @@ func (s *Strategy) ID() string { 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()}) + session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval}) } func (s *Strategy) ClosePosition(ctx context.Context, percentage fixedpoint.Value) error { @@ -85,7 +87,7 @@ func (s *Strategy) ClosePosition(ctx context.Context, percentage fixedpoint.Valu Market: s.Market, } - //s.Notify("Submitting %s %s order to close position by %v", s.Symbol, side.String(), percentage, submitOrder) + // s.Notify("Submitting %s %s order to close position by %v", s.Symbol, side.String(), percentage, submitOrder) createdOrders, err := s.session.Exchange.SubmitOrders(ctx, submitOrder) if err != nil { @@ -99,13 +101,13 @@ func (s *Strategy) ClosePosition(ctx context.Context, percentage fixedpoint.Valu func (s *Strategy) placeOrders(ctx context.Context, orderExecutor bbgo.OrderExecutor, er fixedpoint.Value) { - //if s.prevER.Sign() < 0 && er.Sign() > 0 { + // if s.prevER.Sign() < 0 && er.Sign() > 0 { if er.Sign() >= 0 { submitOrder := types.SubmitOrder{ Symbol: s.Symbol, Side: types.SideTypeBuy, Type: types.OrderTypeMarket, - Quantity: s.Quantity, //er.Abs().Mul(fixedpoint.NewFromInt(20)), + Quantity: s.Quantity, // er.Abs().Mul(fixedpoint.NewFromInt(20)), } createdOrders, err := orderExecutor.SubmitOrders(ctx, submitOrder) if err != nil { @@ -113,13 +115,13 @@ func (s *Strategy) placeOrders(ctx context.Context, orderExecutor bbgo.OrderExec } s.orderStore.Add(createdOrders...) s.activeMakerOrders.Add(createdOrders...) - //} else if s.prevER.Sign() > 0 && er.Sign() < 0 { + // } else if s.prevER.Sign() > 0 && er.Sign() < 0 { } else { submitOrder := types.SubmitOrder{ Symbol: s.Symbol, Side: types.SideTypeSell, Type: types.OrderTypeMarket, - Quantity: s.Quantity, //er.Abs().Mul(fixedpoint.NewFromInt(20)), + Quantity: s.Quantity, // er.Abs().Mul(fixedpoint.NewFromInt(20)), } createdOrders, err := orderExecutor.SubmitOrders(ctx, submitOrder) if err != nil { @@ -144,13 +146,13 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se s.pvDivergence = &Correlation{IntervalWindow: iw} // bind indicator to the data store, so that our callback could be triggered s.pvDivergence.Bind(st) - //s.pvDivergence.OnUpdate(func(corr float64) { + // s.pvDivergence.OnUpdate(func(corr float64) { // //fmt.Printf("now we've got corr: %f\n", corr) - //}) + // }) s.Alpha = [][]float64{{}, {}, {}, {}, {}} s.Ret = []float64{} - //thetas := []float64{0, 0, 0, 0} + // thetas := []float64{0, 0, 0, 0} preCompute := 0 s.activeMakerOrders = bbgo.NewLocalActiveOrderBook(s.Symbol) @@ -198,7 +200,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se s.Alpha[3] = append(s.Alpha[3], mom.Float64()) s.Alpha[4] = append(s.Alpha[4], ogap.Float64()) - //s.Alpha[5] = append(s.Alpha[4], 1.0) // constant + // s.Alpha[5] = append(s.Alpha[4], 1.0) // constant ret := kline.Close.Sub(s.prevClose).Div(s.prevClose).Float64() s.Ret = append(s.Ret, ret) @@ -231,7 +233,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se r.Train(rdp...) r.Run() fmt.Printf("Regression formula:\n%v\n", r.Formula) - //prediction := r.Coeff(0)*corr.Float64() + r.Coeff(1)*rev.Float64() + r.Coeff(2)*factorzoo.Float64() + r.Coeff(3)*mom.Float64() + r.Coeff(4) + // prediction := r.Coeff(0)*corr.Float64() + r.Coeff(1)*rev.Float64() + r.Coeff(2)*factorzoo.Float64() + r.Coeff(3)*mom.Float64() + r.Coeff(4) prediction, _ := r.Predict([]float64{corr.Float64(), rev.Float64(), a150.Float64(), mom.Float64(), ogap.Float64()}) log.Infof("Predicted Return: %f", prediction) diff --git a/pkg/strategy/flashcrash/strategy.go b/pkg/strategy/flashcrash/strategy.go index 662c3385f..58159c21e 100644 --- a/pkg/strategy/flashcrash/strategy.go +++ b/pkg/strategy/flashcrash/strategy.go @@ -106,7 +106,7 @@ func (s *Strategy) updateBidOrders(orderExecutor bbgo.OrderExecutor, session *bb } func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) { - session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: string(s.Interval)}) + session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval}) } func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession) error { diff --git a/pkg/strategy/funding/strategy.go b/pkg/strategy/funding/strategy.go index 937692577..2039eb54d 100644 --- a/pkg/strategy/funding/strategy.go +++ b/pkg/strategy/funding/strategy.go @@ -77,10 +77,10 @@ func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) { for _, detection := range s.SupportDetection { session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{ - Interval: string(detection.Interval), + Interval: detection.Interval, }) session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{ - Interval: string(detection.MovingAverageIntervalWindow.Interval), + Interval: detection.MovingAverageIntervalWindow.Interval, }) } } diff --git a/pkg/strategy/kline/strategy.go b/pkg/strategy/kline/strategy.go index 1dae69be4..2c800efaa 100644 --- a/pkg/strategy/kline/strategy.go +++ b/pkg/strategy/kline/strategy.go @@ -2,6 +2,7 @@ package kline import ( "context" + "github.com/sirupsen/logrus" "github.com/c9s/bbgo/pkg/bbgo" @@ -26,7 +27,7 @@ func (s *Strategy) ID() string { } func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) { - session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: string(s.MovingAverage.Interval)}) + session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.MovingAverage.Interval}) } func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession) error { diff --git a/pkg/strategy/pivotshort/strategy.go b/pkg/strategy/pivotshort/strategy.go index 692b8ae76..6976ee4d8 100644 --- a/pkg/strategy/pivotshort/strategy.go +++ b/pkg/strategy/pivotshort/strategy.go @@ -3,6 +3,7 @@ package pivotshort import ( "context" "fmt" + "github.com/c9s/bbgo/pkg/bbgo" "github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/indicator" @@ -65,9 +66,8 @@ func (s *Strategy) ID() string { 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()}) - //session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: types.Interval1d.String()}) - + session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval}) + //session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: types.Interval1d}) } func (s *Strategy) placeOrder(ctx context.Context, price fixedpoint.Value, qty fixedpoint.Value, orderExecutor bbgo.OrderExecutor) { diff --git a/pkg/strategy/pricealert/strategy.go b/pkg/strategy/pricealert/strategy.go index 0e484e52b..a9b5dcc30 100644 --- a/pkg/strategy/pricealert/strategy.go +++ b/pkg/strategy/pricealert/strategy.go @@ -20,7 +20,7 @@ type Strategy struct { // These fields will be filled from the config file (it translates YAML to JSON) Symbol string `json:"symbol"` - Interval string `json:"interval"` + Interval types.Interval `json:"interval"` MinChange fixedpoint.Value `json:"minChange"` } diff --git a/pkg/strategy/pricedrop/strategy.go b/pkg/strategy/pricedrop/strategy.go index 915f7b59c..bfca2577f 100644 --- a/pkg/strategy/pricedrop/strategy.go +++ b/pkg/strategy/pricedrop/strategy.go @@ -35,7 +35,7 @@ func (s *Strategy) ID() string { } func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) { - session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: string(s.Interval)}) + session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval}) } func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession) error { diff --git a/pkg/strategy/rebalance/strategy.go b/pkg/strategy/rebalance/strategy.go index 64d1c6d5a..e9eb0bc50 100644 --- a/pkg/strategy/rebalance/strategy.go +++ b/pkg/strategy/rebalance/strategy.go @@ -74,7 +74,7 @@ func (s *Strategy) Validate() error { func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) { for _, symbol := range s.getSymbols() { - session.Subscribe(types.KLineChannel, symbol, types.SubscribeOptions{Interval: s.Interval.String()}) + session.Subscribe(types.KLineChannel, symbol, types.SubscribeOptions{Interval: s.Interval}) } } diff --git a/pkg/strategy/schedule/strategy.go b/pkg/strategy/schedule/strategy.go index 4d34263b9..00aa10a46 100644 --- a/pkg/strategy/schedule/strategy.go +++ b/pkg/strategy/schedule/strategy.go @@ -46,12 +46,12 @@ func (s *Strategy) ID() string { } func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) { - session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval.String()}) + session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval}) if s.BelowMovingAverage != nil { - session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.BelowMovingAverage.Interval.String()}) + session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.BelowMovingAverage.Interval}) } if s.AboveMovingAverage != nil { - session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.AboveMovingAverage.Interval.String()}) + session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.AboveMovingAverage.Interval}) } } diff --git a/pkg/strategy/support/strategy.go b/pkg/strategy/support/strategy.go index 91aaeabdd..83768c56b 100644 --- a/pkg/strategy/support/strategy.go +++ b/pkg/strategy/support/strategy.go @@ -202,14 +202,14 @@ func (s *Strategy) Validate() error { } func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) { - session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: string(s.Interval)}) + session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval}) if s.TriggerMovingAverage != zeroiw { - session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: string(s.TriggerMovingAverage.Interval)}) + session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.TriggerMovingAverage.Interval}) } if s.LongTermMovingAverage != zeroiw { - session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: string(s.LongTermMovingAverage.Interval)}) + session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.LongTermMovingAverage.Interval}) } } diff --git a/pkg/strategy/swing/strategy.go b/pkg/strategy/swing/strategy.go index 2d8d9e55b..bd087731e 100644 --- a/pkg/strategy/swing/strategy.go +++ b/pkg/strategy/swing/strategy.go @@ -55,7 +55,7 @@ type Strategy struct { // Interval is the interval of the kline channel we want to subscribe, // the kline event will trigger the strategy to check if we need to submit order. - Interval string `json:"interval"` + Interval types.Interval `json:"interval"` // MinChange filters out the k-lines with small changes. so that our strategy will only be triggered // in specific events. diff --git a/pkg/strategy/techsignal/strategy.go b/pkg/strategy/techsignal/strategy.go index 814af8474..ac1e5145e 100644 --- a/pkg/strategy/techsignal/strategy.go +++ b/pkg/strategy/techsignal/strategy.go @@ -7,9 +7,10 @@ import ( "strings" "time" + "github.com/sirupsen/logrus" + "github.com/c9s/bbgo/pkg/exchange/binance" "github.com/c9s/bbgo/pkg/fixedpoint" - "github.com/sirupsen/logrus" "github.com/c9s/bbgo/pkg/bbgo" "github.com/c9s/bbgo/pkg/types" @@ -69,11 +70,11 @@ func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) { // session.Subscribe(types.BookChannel, s.Symbol, types.SubscribeOptions{}) for _, detection := range s.SupportDetection { session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{ - Interval: string(detection.Interval), + Interval: detection.Interval, }) session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{ - Interval: string(detection.MovingAverageInterval), + Interval: detection.MovingAverageInterval, }) } } diff --git a/pkg/types/stream.go b/pkg/types/stream.go index a45a2d3fc..2363bb215 100644 --- a/pkg/types/stream.go +++ b/pkg/types/stream.go @@ -410,14 +410,14 @@ const ( // SubscribeOptions provides the standard stream options type SubscribeOptions struct { // TODO: change to Interval type later - Interval string `json:"interval,omitempty"` - Depth Depth `json:"depth,omitempty"` - Speed Speed `json:"speed,omitempty"` + Interval Interval `json:"interval,omitempty"` + Depth Depth `json:"depth,omitempty"` + Speed Speed `json:"speed,omitempty"` } func (o SubscribeOptions) String() string { if len(o.Interval) > 0 { - return o.Interval + return string(o.Interval) } return string(o.Depth)