mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-22 06:53:52 +00:00
Merge pull request #960 from c9s/refactor/notification
improve: improve the existing notification switch settings
This commit is contained in:
commit
17b5e3566a
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -3,6 +3,11 @@ notifications:
|
|||
slack:
|
||||
defaultChannel: "bbgo"
|
||||
errorChannel: "bbgo-error"
|
||||
switches:
|
||||
trade: true
|
||||
orderUpdate: true
|
||||
submitOrder: true
|
||||
|
||||
|
||||
exchangeStrategies:
|
||||
- on: max
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -3,6 +3,10 @@ notifications:
|
|||
slack:
|
||||
defaultChannel: "bbgo"
|
||||
errorChannel: "bbgo-error"
|
||||
switches:
|
||||
trade: true
|
||||
orderUpdate: true
|
||||
submitOrder: true
|
||||
|
||||
exchangeStrategies:
|
||||
- on: max
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
},
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue
Block a user