diff --git a/config/bollgrid.yaml b/config/bollgrid.yaml index bef337112..3ecfc78f7 100644 --- a/config/bollgrid.yaml +++ b/config/bollgrid.yaml @@ -3,19 +3,10 @@ notifications: slack: defaultChannel: "dev-bbgo" errorChannel: "bbgo-error" - - # if you want to route channel by symbol - symbolChannels: - "^BTC": "btc" - "^ETH": "eth" - "^BNB": "bnb" - - # object routing rules - routing: - trade: "$symbol" - order: "$symbol" - submitOrder: "$session" # not supported yet - pnL: "bbgo-pnl" + switches: + trade: true + orderUpdate: true + submitOrder: true sessions: # binance: diff --git a/config/funding.yaml b/config/funding.yaml index 0fcd433ed..9f7e7352b 100644 --- a/config/funding.yaml +++ b/config/funding.yaml @@ -4,17 +4,10 @@ notifications: defaultChannel: "dev-bbgo" errorChannel: "bbgo-error" - # if you want to route channel by symbol - symbolChannels: - "^BTC": "btc" - "^ETH": "eth" - - # object routing rules - routing: - trade: "$symbol" - order: "$symbol" - submitOrder: "$session" # not supported yet - pnL: "bbgo-pnl" + switches: + trade: true + orderUpdate: true + submitOrder: true sessions: binance: diff --git a/config/marketcap.yaml b/config/marketcap.yaml index c3e7b7285..cea8ef9ea 100644 --- a/config/marketcap.yaml +++ b/config/marketcap.yaml @@ -3,6 +3,11 @@ notifications: slack: defaultChannel: "bbgo" errorChannel: "bbgo-error" + switches: + trade: true + orderUpdate: true + submitOrder: true + exchangeStrategies: - on: max diff --git a/config/pricealert.yaml b/config/pricealert.yaml index 2b7180285..1662c50d5 100644 --- a/config/pricealert.yaml +++ b/config/pricealert.yaml @@ -4,17 +4,10 @@ notifications: defaultChannel: "dev-bbgo" errorChannel: "bbgo-error" - # if you want to route channel by symbol - symbolChannels: - "^BTC": "btc" - "^ETH": "eth" - - # object routing rules - routing: - trade: "$symbol" - order: "$symbol" - submitOrder: "$session" # not supported yet - pnL: "bbgo-pnl" + switches: + trade: true + orderUpdate: true + submitOrder: true sessions: binance: diff --git a/config/pricedrop.yaml b/config/pricedrop.yaml index e650a981c..295a8e845 100644 --- a/config/pricedrop.yaml +++ b/config/pricedrop.yaml @@ -3,16 +3,10 @@ notifications: slack: defaultChannel: "bbgo" errorChannel: "bbgo-error" - -reportPnL: -- averageCostBySymbols: - - "BTCUSDT" - - "ETHUSDT" - - "BNBUSDT" - of: binance - when: - - "@daily" - - "@hourly" + switches: + trade: true + orderUpdate: true + submitOrder: true sessions: binance: diff --git a/config/rebalance.yaml b/config/rebalance.yaml index 6780da1d3..2038a70d2 100644 --- a/config/rebalance.yaml +++ b/config/rebalance.yaml @@ -3,6 +3,10 @@ notifications: slack: defaultChannel: "bbgo" errorChannel: "bbgo-error" + switches: + trade: true + orderUpdate: true + submitOrder: true exchangeStrategies: - on: max diff --git a/config/support-margin.yaml b/config/support-margin.yaml index bc28cea49..d04614ad2 100644 --- a/config/support-margin.yaml +++ b/config/support-margin.yaml @@ -4,18 +4,10 @@ notifications: defaultChannel: "dev-bbgo" errorChannel: "bbgo-error" - # if you want to route channel by symbol - symbolChannels: - "^BTC": "btc" - "^ETH": "eth" - "^BNB": "bnb" - - # object routing rules - routing: - trade: "$symbol" - order: "$symbol" - submitOrder: "$session" # not supported yet - pnL: "bbgo-pnl" + switches: + trade: true + orderUpdate: true + submitOrder: true sessions: binance_margin_linkusdt: diff --git a/config/support.yaml b/config/support.yaml index b0f1eefbd..221ea574f 100644 --- a/config/support.yaml +++ b/config/support.yaml @@ -3,11 +3,10 @@ notifications: slack: defaultChannel: "dev-bbgo" errorChannel: "bbgo-error" - # object routing rules - routing: - trade: "$symbol" - order: "$symbol" - submitOrder: "$session" # not supported yet + switches: + trade: true + orderUpdate: true + submitOrder: true sessions: binance: diff --git a/config/swing.yaml b/config/swing.yaml index 764fa5a12..45625eda2 100644 --- a/config/swing.yaml +++ b/config/swing.yaml @@ -4,18 +4,10 @@ notifications: defaultChannel: "dev-bbgo" errorChannel: "bbgo-error" - # if you want to route channel by symbol - symbolChannels: - "^BTC": "btc" - "^ETH": "eth" - "^BNB": "bnb" - - # object routing rules - routing: - trade: "$symbol" - order: "$symbol" - submitOrder: "$session" # not supported yet - pnL: "bbgo-pnl" + switches: + trade: true + orderUpdate: true + submitOrder: true sessions: binance: diff --git a/config/xbalance.yaml b/config/xbalance.yaml index a437fc2ec..e3f88005e 100644 --- a/config/xbalance.yaml +++ b/config/xbalance.yaml @@ -4,22 +4,10 @@ notifications: defaultChannel: "dev-bbgo" errorChannel: "bbgo-error" - # if you want to route channel by symbol - symbolChannels: - "^BTC": "btc" - "^ETH": "eth" - - # if you want to route channel by exchange session - sessionChannels: - max: "bbgo-max" - binance: "bbgo-binance" - - # routing rules - routing: - trade: "$symbol" - order: "$slient" - submitOrder: "$slient" - pnL: "bbgo-pnl" + switches: + trade: true + orderUpdate: true + submitOrder: true sessions: max: diff --git a/config/xgap.yaml b/config/xgap.yaml index 89d732986..03b12d6d5 100644 --- a/config/xgap.yaml +++ b/config/xgap.yaml @@ -4,22 +4,10 @@ notifications: defaultChannel: "dev-bbgo" errorChannel: "bbgo-error" - # if you want to route channel by symbol - symbolChannels: - "^BTC": "btc" - "^ETH": "eth" - - # if you want to route channel by exchange session - sessionChannels: - max: "bbgo-max" - binance: "bbgo-binance" - - # routing rules - routing: - trade: "$silent" - order: "$silent" - submitOrder: "$silent" - pnL: "bbgo-pnl" + switches: + trade: true + orderUpdate: true + submitOrder: true persistence: json: diff --git a/config/xmaker-btcusdt.yaml b/config/xmaker-btcusdt.yaml index 6beb4bd52..4dfa95a5f 100644 --- a/config/xmaker-btcusdt.yaml +++ b/config/xmaker-btcusdt.yaml @@ -4,22 +4,10 @@ notifications: defaultChannel: "dev-bbgo" errorChannel: "bbgo-error" - # if you want to route channel by symbol - symbolChannels: - "^BTC": "btc" - "^ETH": "eth" - - # if you want to route channel by exchange session - sessionChannels: - max: "bbgo-max" - binance: "bbgo-binance" - - # routing rules - routing: - trade: "$symbol" - order: "$silent" - submitOrder: "$silent" - pnL: "bbgo-pnl" + switches: + trade: true + orderUpdate: true + submitOrder: true reportPnL: - averageCostBySymbols: diff --git a/config/xmaker-ethusdt.yaml b/config/xmaker-ethusdt.yaml index b7faef1f4..f4a0181d9 100644 --- a/config/xmaker-ethusdt.yaml +++ b/config/xmaker-ethusdt.yaml @@ -4,22 +4,10 @@ notifications: defaultChannel: "dev-bbgo" errorChannel: "bbgo-error" - # if you want to route channel by symbol - symbolChannels: - "^BTC": "btc" - "^ETH": "eth" - - # if you want to route channel by exchange session - sessionChannels: - max: "bbgo-max" - binance: "bbgo-binance" - - # routing rules - routing: - trade: "$symbol" - order: "$silent" - submitOrder: "$silent" - pnL: "bbgo-pnl" + switches: + trade: true + orderUpdate: false + submitOrder: false persistence: json: diff --git a/config/xmaker.yaml b/config/xmaker.yaml index 293b58247..323bf130d 100644 --- a/config/xmaker.yaml +++ b/config/xmaker.yaml @@ -4,11 +4,10 @@ notifications: defaultChannel: "dev-bbgo" errorChannel: "bbgo-error" - # routing rules - routing: - trade: "$silent" - order: "$silent" - submitOrder: "$silent" + switches: + trade: true + orderUpdate: false + submitOrder: false persistence: json: diff --git a/config/xnav.yaml b/config/xnav.yaml index e31a54b66..2e59eef84 100644 --- a/config/xnav.yaml +++ b/config/xnav.yaml @@ -4,22 +4,10 @@ notifications: defaultChannel: "dev-bbgo" errorChannel: "bbgo-error" - # if you want to route channel by symbol - symbolChannels: - "^BTC": "btc" - "^ETH": "eth" - - # if you want to route channel by exchange session - sessionChannels: - max: "bbgo-max" - binance: "bbgo-binance" - - # routing rules - routing: - trade: "$symbol" - order: "$slient" - submitOrder: "$slient" - pnL: "bbgo-pnl" + switches: + trade: true + orderUpdate: true + submitOrder: true sessions: max: diff --git a/config/xpuremaker.yaml b/config/xpuremaker.yaml index b089a1adb..697fdfeb7 100644 --- a/config/xpuremaker.yaml +++ b/config/xpuremaker.yaml @@ -4,14 +4,10 @@ notifications: defaultChannel: "bbgo" errorChannel: "bbgo-error" -reportPnL: -- averageCostBySymbols: - - "BTCUSDT" - - "BNBUSDT" - of: binance - when: - - "@daily" - - "@hourly" + switches: + trade: true + orderUpdate: true + submitOrder: true sessions: max: diff --git a/pkg/bbgo/config.go b/pkg/bbgo/config.go index d5164962e..5f51624b7 100644 --- a/pkg/bbgo/config.go +++ b/pkg/bbgo/config.go @@ -76,15 +76,17 @@ type TelegramNotification struct { Broadcast bool `json:"broadcast" yaml:"broadcast"` } +type NotificationSwitches struct { + Trade bool `json:"trade" yaml:"trade"` + Position bool `json:"position" yaml:"position"` + OrderUpdate bool `json:"orderUpdate" yaml:"orderUpdate"` + SubmitOrder bool `json:"submitOrder" yaml:"submitOrder"` +} + type NotificationConfig struct { - Slack *SlackNotification `json:"slack,omitempty" yaml:"slack,omitempty"` - + Slack *SlackNotification `json:"slack,omitempty" yaml:"slack,omitempty"` Telegram *TelegramNotification `json:"telegram,omitempty" yaml:"telegram,omitempty"` - - SymbolChannels map[string]string `json:"symbolChannels,omitempty" yaml:"symbolChannels,omitempty"` - SessionChannels map[string]string `json:"sessionChannels,omitempty" yaml:"sessionChannels,omitempty"` - - Routing *SlackNotificationRouting `json:"routing,omitempty" yaml:"routing,omitempty"` + Switches *NotificationSwitches `json:"switches" yaml:"switches"` } type Session struct { diff --git a/pkg/bbgo/config_test.go b/pkg/bbgo/config_test.go index 74d13ca66..2598a52fc 100644 --- a/pkg/bbgo/config_test.go +++ b/pkg/bbgo/config_test.go @@ -48,13 +48,6 @@ func TestLoadConfig(t *testing.T) { wantErr: false, f: func(t *testing.T, config *Config) { assert.NotNil(t, config.Notifications) - assert.NotNil(t, config.Notifications.SessionChannels) - assert.NotNil(t, config.Notifications.SymbolChannels) - assert.Equal(t, map[string]string{ - "^BTC": "#btc", - "^ETH": "#eth", - }, config.Notifications.SymbolChannels) - assert.NotNil(t, config.Notifications.Routing) assert.Equal(t, "#dev-bbgo", config.Notifications.Slack.DefaultChannel) assert.Equal(t, "#error", config.Notifications.Slack.ErrorChannel) }, diff --git a/pkg/bbgo/environment.go b/pkg/bbgo/environment.go index 639a7fbe7..4ea457830 100644 --- a/pkg/bbgo/environment.go +++ b/pkg/bbgo/environment.go @@ -30,7 +30,6 @@ import ( "github.com/c9s/bbgo/pkg/slack/slacklog" "github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/util" - "github.com/c9s/bbgo/pkg/util/templateutil" ) func init() { @@ -302,153 +301,6 @@ func (environ *Environment) ConfigurePersistence(conf *PersistenceConfig) error return nil } -// ConfigureNotificationRouting configures the notification rules -// for symbol-based routes, we should register the same symbol rules for each session. -// for session-based routes, we should set the fixed callbacks for each session -func (environ *Environment) ConfigureNotificationRouting(conf *NotificationConfig) error { - // configure routing here - if conf.SymbolChannels != nil { - Notification.SymbolChannelRouter.AddRoute(conf.SymbolChannels) - } - if conf.SessionChannels != nil { - Notification.SessionChannelRouter.AddRoute(conf.SessionChannels) - } - if conf.Routing != nil { - // configure passive object notification routing - switch conf.Routing.Trade { - case "$silent": // silent, do not setup notification - - case "$session": - defaultTradeUpdateHandler := func(trade types.Trade) { - Notify(&trade) - } - for name := range environ.sessions { - session := environ.sessions[name] - - // if we can route session name to channel successfully... - channel, ok := Notification.SessionChannelRouter.Route(name) - if ok { - session.UserDataStream.OnTradeUpdate(func(trade types.Trade) { - Notification.NotifyTo(channel, &trade) - }) - } else { - session.UserDataStream.OnTradeUpdate(defaultTradeUpdateHandler) - } - } - - case "$symbol": - // configure object routes for Trade - Notification.ObjectChannelRouter.Route(func(obj interface{}) (channel string, ok bool) { - trade, matched := obj.(*types.Trade) - if !matched { - return - } - channel, ok = Notification.SymbolChannelRouter.Route(trade.Symbol) - return - }) - - // use same handler for each session - handler := func(trade types.Trade) { - channel, ok := Notification.RouteObject(&trade) - if ok { - NotifyTo(channel, &trade) - } else { - Notify(&trade) - } - } - for _, session := range environ.sessions { - session.UserDataStream.OnTradeUpdate(handler) - } - } - - switch conf.Routing.Order { - - case "$silent": // silent, do not setup notification - - case "$session": - defaultOrderUpdateHandler := func(order types.Order) { - text := templateutil.Render(TemplateOrderReport, order) - Notify(text, &order) - } - for name := range environ.sessions { - session := environ.sessions[name] - - // if we can route session name to channel successfully... - channel, ok := Notification.SessionChannelRouter.Route(name) - if ok { - session.UserDataStream.OnOrderUpdate(func(order types.Order) { - text := templateutil.Render(TemplateOrderReport, order) - NotifyTo(channel, text, &order) - }) - } else { - session.UserDataStream.OnOrderUpdate(defaultOrderUpdateHandler) - } - } - - case "$symbol": - // add object route - Notification.ObjectChannelRouter.Route(func(obj interface{}) (channel string, ok bool) { - order, matched := obj.(*types.Order) - if !matched { - return - } - channel, ok = Notification.SymbolChannelRouter.Route(order.Symbol) - return - }) - - // use same handler for each session - handler := func(order types.Order) { - text := templateutil.Render(TemplateOrderReport, order) - channel, ok := Notification.RouteObject(&order) - if ok { - NotifyTo(channel, text, &order) - } else { - Notify(text, &order) - } - } - for _, session := range environ.sessions { - session.UserDataStream.OnOrderUpdate(handler) - } - } - - switch conf.Routing.SubmitOrder { - - case "$silent": // silent, do not setup notification - - case "$symbol": - // add object route - Notification.ObjectChannelRouter.Route(func(obj interface{}) (channel string, ok bool) { - order, matched := obj.(*types.SubmitOrder) - if !matched { - return - } - - channel, ok = Notification.SymbolChannelRouter.Route(order.Symbol) - return - }) - - } - - // currently, not used - // FIXME: this is causing cyclic import - /* - switch conf.Routing.PnL { - case "$symbol": - environ.ObjectChannelRouter.Route(func(obj interface{}) (channel string, ok bool) { - report, matched := obj.(*pnl.AverageCostPnlReport) - if !matched { - return - } - channel, ok = environ.SymbolChannelRouter.Route(report.Symbol) - return - }) - } - */ - - } - return nil -} - func (environ *Environment) SetStartTime(t time.Time) *Environment { environ.startTime = t return environ @@ -773,16 +625,9 @@ func (environ *Environment) syncSession(ctx context.Context, session *ExchangeSe } func (environ *Environment) ConfigureNotificationSystem(userConfig *Config) error { - // setup default notification config if userConfig.Notifications == nil { - userConfig.Notifications = &NotificationConfig{ - Routing: &SlackNotificationRouting{ - Trade: "$session", - Order: "$silent", - SubmitOrder: "$silent", - }, - } + userConfig.Notifications = &NotificationConfig{} } var persistence = PersistenceServiceFacade.Get() @@ -807,7 +652,7 @@ func (environ *Environment) ConfigureNotificationSystem(userConfig *Config) erro } if userConfig.Notifications != nil { - if err := environ.ConfigureNotificationRouting(userConfig.Notifications); err != nil { + if err := environ.ConfigureNotification(userConfig.Notifications); err != nil { return err } } @@ -815,6 +660,32 @@ func (environ *Environment) ConfigureNotificationSystem(userConfig *Config) erro return nil } +func (environ *Environment) ConfigureNotification(config *NotificationConfig) error { + if config.Switches != nil { + if config.Switches.Trade { + tradeHandler := func(trade types.Trade) { + Notify(trade) + } + + for _, session := range environ.sessions { + session.UserDataStream.OnTradeUpdate(tradeHandler) + } + } + + if config.Switches.OrderUpdate { + orderUpdateHandler := func(order types.Order) { + Notify(order) + } + + for _, session := range environ.sessions { + session.UserDataStream.OnOrderUpdate(orderUpdateHandler) + } + } + } + + return nil +} + // getAuthStoreID returns the authentication store id // if telegram bot token is defined, the bot id will be used. // if not, env var $USER will be used.