Skip to content

Commit e310ea9

Browse files
committed
all: add livenote and livenoteposter, move all example strategy into pkg/strategy/example
1 parent d8150a1 commit e310ea9

File tree

10 files changed

+101
-7
lines changed

10 files changed

+101
-7
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -392,10 +392,10 @@ persistence:
392392
393393
Check out the strategy directory [strategy](pkg/strategy) for all built-in strategies:
394394
395-
- `pricealert` strategy demonstrates how to use the notification system [pricealert](pkg/strategy/pricealert). See
395+
- `pricealert` strategy demonstrates how to use the notification system [pricealert](pkg/strategy/example/pricealert). See
396396
[document](./doc/strategy/pricealert.md).
397397
- `buyandhold` strategy demonstrates how to subscribe kline events and submit market
398-
order [buyandhold](pkg/strategy/pricedrop)
398+
order [buyandhold](pkg/strategy/example/pricedrop)
399399
- `bollgrid` strategy implements a basic grid strategy with the built-in bollinger
400400
indicator [bollgrid](pkg/strategy/bollgrid)
401401
- `grid` strategy implements the fixed price band grid strategy [grid](pkg/strategy/grid). See

README.zh_TW.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,8 @@ persistence:
370370
371371
查看策略目錄 [strategy](pkg/strategy) 以獲得所有內置策略:
372372
373-
- `pricealert` 策略演示如何使用通知系統 [pricealert](pkg/strategy/pricealert)。參見[文件](./doc/strategy/pricealert.md).
374-
- `buyandhold` 策略演示如何訂閱 kline 事件並提交市場訂單 [buyandhold](pkg/strategy/pricedrop)
373+
- `pricealert` 策略演示如何使用通知系統 [pricealert](pkg/strategy/example/pricealert)。參見[文件](./doc/strategy/pricealert.md).
374+
- `buyandhold` 策略演示如何訂閱 kline 事件並提交市場訂單 [buyandhold](pkg/strategy/example/pricedrop)
375375
- `bollgrid` 策略實現了一個基本的網格策略,使用內置的布林通道指標 [bollgrid](pkg/strategy/bollgrid)
376376
- `grid` 策略實現了固定價格帶網格策略 [grid](pkg/strategy/grid)。參見[文件](./doc/strategy/grid.md).
377377
- `supertrend` 策略使用 Supertrend 指標作為趨勢,並使用 DEMA 指標作為噪聲
@@ -621,4 +621,4 @@ make embed && go run -tags web ./cmd/bbgo-lorca
621621

622622
## 授權
623623

624-
AGPL 授權
624+
AGPL 授權

pkg/bbgo/livenote.go

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package bbgo
2+
3+
import (
4+
"github.com/sirupsen/logrus"
5+
6+
"github.com/c9s/bbgo/pkg/types"
7+
)
8+
9+
// PostLiveNote posts a live note to slack or other services
10+
// The MessageID will be set after the message is posted if it's not set.
11+
func PostLiveNote(note *types.LiveNote) {
12+
for _, poster := range Notification.liveNotePosters {
13+
if err := poster.PostLiveNote(note); err != nil {
14+
logrus.WithError(err).Errorf("unable to post live note: %+v", note)
15+
}
16+
}
17+
}
18+
19+
type LiveNotePoster interface {
20+
PostLiveNote(note *types.LiveNote) error
21+
}

pkg/bbgo/notification.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ func (n *NullNotifier) SendPhoto(buffer *bytes.Buffer) {}
4848
func (n *NullNotifier) SendPhotoTo(channel string, buffer *bytes.Buffer) {}
4949

5050
type Notifiability struct {
51-
notifiers []Notifier
51+
notifiers []Notifier
52+
liveNotePosters []LiveNotePoster
53+
5254
SessionChannelRouter *PatternChannelRouter `json:"-"`
5355
SymbolChannelRouter *PatternChannelRouter `json:"-"`
5456
ObjectChannelRouter *ObjectChannelRouter `json:"-"`
@@ -81,6 +83,10 @@ func (m *Notifiability) RouteObject(obj interface{}) (channel string, ok bool) {
8183
// AddNotifier adds the notifier that implements the Notifier interface.
8284
func (m *Notifiability) AddNotifier(notifier Notifier) {
8385
m.notifiers = append(m.notifiers, notifier)
86+
87+
if poster, ok := notifier.(LiveNotePoster); ok {
88+
m.liveNotePosters = append(m.liveNotePosters, poster)
89+
}
8490
}
8591

8692
func (m *Notifiability) Notify(obj interface{}, args ...interface{}) {

pkg/notifier/slacknotifier/slack.go

+35-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ func (n *Notifier) worker() {
5454
return
5555

5656
case task := <-n.taskC:
57-
limiter.Wait(ctx)
57+
// ignore the wait error
58+
_ = limiter.Wait(ctx)
5859

5960
_, _, err := n.client.PostMessageContext(ctx, task.Channel, task.Opts...)
6061
if err != nil {
@@ -66,7 +67,40 @@ func (n *Notifier) worker() {
6667
}
6768
}
6869

70+
func (n *Notifier) PostLiveNote(note *types.LiveNote) error {
71+
ctx := context.Background()
72+
73+
channel := note.ChannelID
74+
if channel == "" {
75+
channel = n.channel
76+
}
77+
78+
if note.MessageID != "" {
79+
// UpdateMessageContext returns channel, timestamp, text, err
80+
_, _, _, err := n.client.UpdateMessageContext(ctx, channel, note.MessageID, slack.MsgOptionText(note.ObjectID(), true))
81+
if err != nil {
82+
return err
83+
}
84+
85+
} else {
86+
87+
respCh, respTs, err := n.client.PostMessageContext(ctx, channel)
88+
if err != nil {
89+
log.WithError(err).
90+
WithField("channel", n.channel).
91+
Errorf("slack api error: %s", err.Error())
92+
return err
93+
}
94+
95+
note.SetChannelID(respCh)
96+
note.SetMessageID(respTs)
97+
}
98+
99+
return nil
100+
}
101+
69102
func (n *Notifier) Notify(obj interface{}, args ...interface{}) {
103+
// TODO: filter args for the channel option
70104
n.NotifyTo(n.channel, obj, args...)
71105
}
72106

File renamed without changes.
File renamed without changes.
File renamed without changes.

pkg/types/livenote.go

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package types
2+
3+
type LiveNoteObject interface {
4+
ObjectID() string
5+
}
6+
7+
type LiveNote struct {
8+
// MessageID is the unique identifier of the message
9+
// for slack, it's the timestamp of the message
10+
MessageID string `json:"messageId"`
11+
12+
ChannelID string `json:"channelId"`
13+
14+
Object LiveNoteObject
15+
}
16+
17+
func NewLiveNote(object LiveNoteObject) *LiveNote {
18+
return &LiveNote{
19+
Object: object,
20+
}
21+
}
22+
23+
func (n *LiveNote) ObjectID() string {
24+
return n.Object.ObjectID()
25+
}
26+
27+
func (n *LiveNote) SetMessageID(messageID string) {
28+
n.MessageID = messageID
29+
}
30+
31+
func (n *LiveNote) SetChannelID(channelID string) {
32+
n.ChannelID = channelID
33+
}

0 commit comments

Comments
 (0)