mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-24 07:45:15 +00:00
all: add more livenote support
This commit is contained in:
parent
0e2eb8ba54
commit
73b3c5b6dd
16
config/example/livenote.yaml
Normal file
16
config/example/livenote.yaml
Normal file
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
notifications:
|
||||
slack:
|
||||
defaultChannel: "dev-bbgo"
|
||||
errorChannel: "dev-bbgo"
|
||||
|
||||
sessions:
|
||||
binance:
|
||||
exchange: binance
|
||||
envVarPrefix: binance
|
||||
|
||||
exchangeStrategies:
|
||||
- on: binance
|
||||
livenote:
|
||||
symbol: BTCUSDT
|
||||
interval: 5m
|
|
@ -22,4 +22,4 @@ Setup Telegram/Slack notification before using Price Alert Strategy. See [Settin
|
|||
|
||||
#### Examples
|
||||
|
||||
See [pricealert.yaml](../../config/pricealert.yaml) and [pricealert-tg.yaml](../../config/pricealert-tg.yaml)
|
||||
See [pricealert.yaml](../../config/example/pricealert.yaml) and [pricealert-tg.yaml](../../config/pricealert-tg.yaml)
|
||||
|
|
|
@ -9,6 +9,11 @@ import (
|
|||
// PostLiveNote posts a live note to slack or other services
|
||||
// The MessageID will be set after the message is posted if it's not set.
|
||||
func PostLiveNote(obj livenote.Object) {
|
||||
if len(Notification.liveNotePosters) == 0 {
|
||||
logrus.Warn("no live note poster is registered")
|
||||
return
|
||||
}
|
||||
|
||||
for _, poster := range Notification.liveNotePosters {
|
||||
if err := poster.PostLiveNote(obj); err != nil {
|
||||
logrus.WithError(err).Errorf("unable to post live note: %+v", obj)
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
_ "github.com/c9s/bbgo/pkg/strategy/emastop"
|
||||
_ "github.com/c9s/bbgo/pkg/strategy/etf"
|
||||
_ "github.com/c9s/bbgo/pkg/strategy/ewoDgtrd"
|
||||
_ "github.com/c9s/bbgo/pkg/strategy/example/kline"
|
||||
_ "github.com/c9s/bbgo/pkg/strategy/example/livenote"
|
||||
_ "github.com/c9s/bbgo/pkg/strategy/example/pricealert"
|
||||
_ "github.com/c9s/bbgo/pkg/strategy/example/pricedrop"
|
||||
|
@ -30,7 +31,6 @@ import (
|
|||
_ "github.com/c9s/bbgo/pkg/strategy/grid2"
|
||||
_ "github.com/c9s/bbgo/pkg/strategy/harmonic"
|
||||
_ "github.com/c9s/bbgo/pkg/strategy/irr"
|
||||
_ "github.com/c9s/bbgo/pkg/strategy/kline"
|
||||
_ "github.com/c9s/bbgo/pkg/strategy/linregmaker"
|
||||
_ "github.com/c9s/bbgo/pkg/strategy/liquiditymaker"
|
||||
_ "github.com/c9s/bbgo/pkg/strategy/marketcap"
|
||||
|
|
|
@ -33,6 +33,10 @@ func (n *LiveNote) ObjectID() string {
|
|||
return n.cachedObjID
|
||||
}
|
||||
|
||||
func (n *LiveNote) SetObject(object Object) {
|
||||
n.Object = object
|
||||
}
|
||||
|
||||
func (n *LiveNote) SetMessageID(messageID string) {
|
||||
n.MessageID = messageID
|
||||
}
|
||||
|
@ -46,9 +50,9 @@ type Pool struct {
|
|||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func NewPool() *Pool {
|
||||
func NewPool(size int64) *Pool {
|
||||
return &Pool{
|
||||
notes: make(map[string]*LiveNote, 100),
|
||||
notes: make(map[string]*LiveNote, size),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,6 +64,8 @@ func (p *Pool) Update(obj Object) *LiveNote {
|
|||
|
||||
for _, note := range p.notes {
|
||||
if note.ObjectID() == objID {
|
||||
// update the object inside the note
|
||||
note.SetObject(obj)
|
||||
return note
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
func TestLiveNotePool(t *testing.T) {
|
||||
t.Run("same-kline", func(t *testing.T) {
|
||||
pool := NewPool()
|
||||
pool := NewPool(100)
|
||||
k := &types.KLine{
|
||||
Symbol: "BTCUSDT",
|
||||
Interval: types.Interval1m,
|
||||
|
@ -24,7 +24,7 @@ func TestLiveNotePool(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("different-kline", func(t *testing.T) {
|
||||
pool := NewPool()
|
||||
pool := NewPool(100)
|
||||
k := &types.KLine{
|
||||
Symbol: "BTCUSDT",
|
||||
Interval: types.Interval1m,
|
||||
|
|
|
@ -27,6 +27,8 @@ type Notifier struct {
|
|||
channel string
|
||||
|
||||
taskC chan notifyTask
|
||||
|
||||
liveNotePool *livenote.Pool
|
||||
}
|
||||
|
||||
type NotifyOption func(notifier *Notifier)
|
||||
|
@ -36,6 +38,7 @@ func New(client *slack.Client, channel string, options ...NotifyOption) *Notifie
|
|||
channel: channel,
|
||||
client: client,
|
||||
taskC: make(chan notifyTask, 100),
|
||||
liveNotePool: livenote.NewPool(100),
|
||||
}
|
||||
|
||||
for _, o := range options {
|
||||
|
@ -69,8 +72,7 @@ func (n *Notifier) worker() {
|
|||
}
|
||||
|
||||
func (n *Notifier) PostLiveNote(obj livenote.Object) error {
|
||||
// TODO: maintain the object pool for live notes
|
||||
var note = livenote.NewLiveNote(obj)
|
||||
note := n.liveNotePool.Update(obj)
|
||||
ctx := context.Background()
|
||||
|
||||
channel := note.ChannelID
|
||||
|
@ -78,16 +80,25 @@ func (n *Notifier) PostLiveNote(obj livenote.Object) error {
|
|||
channel = n.channel
|
||||
}
|
||||
|
||||
var attachment slack.Attachment
|
||||
if creator, ok := note.Object.(types.SlackAttachmentCreator); ok {
|
||||
attachment = creator.SlackAttachment()
|
||||
} else {
|
||||
return fmt.Errorf("livenote object does not support types.SlackAttachmentCreator interface")
|
||||
}
|
||||
|
||||
opts := slack.MsgOptionAttachments(attachment)
|
||||
|
||||
if note.MessageID != "" {
|
||||
// UpdateMessageContext returns channel, timestamp, text, err
|
||||
_, _, _, err := n.client.UpdateMessageContext(ctx, channel, note.MessageID, slack.MsgOptionText(note.ObjectID(), true))
|
||||
_, _, _, err := n.client.UpdateMessageContext(ctx, channel, note.MessageID, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
respCh, respTs, err := n.client.PostMessageContext(ctx, channel)
|
||||
respCh, respTs, err := n.client.PostMessageContext(ctx, channel, opts)
|
||||
if err != nil {
|
||||
log.WithError(err).
|
||||
WithField("channel", n.channel).
|
||||
|
|
|
@ -50,7 +50,8 @@ func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) {
|
|||
// This strategy simply spent all available quote currency to buy the symbol whenever kline gets closed
|
||||
func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession) error {
|
||||
callback := func(k types.KLine) {
|
||||
// bbgo.PostLiveNote(k)
|
||||
log.Info(k)
|
||||
bbgo.PostLiveNote(&k)
|
||||
}
|
||||
|
||||
// register our kline event handler
|
||||
|
|
|
@ -6,8 +6,9 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/slack-go/slack"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
)
|
||||
|
||||
type DepositStatus string
|
||||
|
@ -64,6 +65,10 @@ func (d Deposit) EffectiveTime() time.Time {
|
|||
return d.Time.Time()
|
||||
}
|
||||
|
||||
func (d *Deposit) ObjectID() string {
|
||||
return "deposit-" + d.Exchange.String() + "-" + d.Asset + "-" + d.Address + "-" + d.TransactionID
|
||||
}
|
||||
|
||||
func (d Deposit) String() (o string) {
|
||||
o = fmt.Sprintf("%s deposit %s %v <- ", d.Exchange, d.Asset, d.Amount)
|
||||
|
||||
|
|
|
@ -284,8 +284,9 @@ func (k *KLine) SlackAttachment() slack.Attachment {
|
|||
Short: true,
|
||||
},
|
||||
},
|
||||
Footer: "",
|
||||
FooterIcon: "",
|
||||
|
||||
FooterIcon: ExchangeFooterIcon(k.Exchange),
|
||||
Footer: k.StartTime.String() + " ~ " + k.EndTime.String(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -317,6 +317,10 @@ func (o Order) CsvRecords() [][]string {
|
|||
}
|
||||
}
|
||||
|
||||
func (o *Order) ObjectID() string {
|
||||
return "order-" + o.Exchange.String() + "-" + o.Symbol + "-" + strconv.FormatUint(o.OrderID, 10)
|
||||
}
|
||||
|
||||
// Backup backs up the current order quantity to a SubmitOrder object
|
||||
// so that we can post the order later when we want to restore the orders.
|
||||
func (o Order) Backup() SubmitOrder {
|
||||
|
|
|
@ -208,7 +208,6 @@ func (trade Trade) SlackAttachment() slack.Attachment {
|
|||
|
||||
liquidity := trade.Liquidity()
|
||||
text := templateutil.Render(slackTradeTextTemplate, trade)
|
||||
footerIcon := ExchangeFooterIcon(trade.Exchange)
|
||||
|
||||
return slack.Attachment{
|
||||
Text: text,
|
||||
|
@ -225,7 +224,7 @@ func (trade Trade) SlackAttachment() slack.Attachment {
|
|||
{Title: "Liquidity", Value: liquidity, Short: true},
|
||||
{Title: "Order ID", Value: strconv.FormatUint(trade.OrderID, 10), Short: true},
|
||||
},
|
||||
FooterIcon: footerIcon,
|
||||
FooterIcon: ExchangeFooterIcon(trade.Exchange),
|
||||
Footer: strings.ToLower(trade.Exchange.String()) + templateutil.Render(" creation time {{ . }}", trade.Time.Time().Format(time.StampMilli)),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user