Skip to content

Commit

Permalink
livenote: add test and generate diff summary for object change
Browse files Browse the repository at this point in the history
  • Loading branch information
c9s committed Nov 11, 2024
1 parent c4c6a73 commit c289c2d
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 25 deletions.
47 changes: 47 additions & 0 deletions pkg/dynamic/compare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/stretchr/testify/assert"

"github.com/c9s/bbgo/pkg/fixedpoint"
. "github.com/c9s/bbgo/pkg/testing/testhelper"
"github.com/c9s/bbgo/pkg/types"
)

Expand Down Expand Up @@ -94,6 +95,52 @@ func Test_Compare(t *testing.T) {
},
},
},
{
name: "kline",
wantErr: assert.NoError,
a: types.KLine{
Open: Number(60000),
High: Number(61000),
Low: Number(59500),
Close: Number(60100),
},
b: types.KLine{
Open: Number(60000),
High: Number(61000),
Low: Number(59500),
Close: Number(60200),
},
want: []Diff{
{
Field: "Close",
Before: "60200",
After: "60100",
},
},
},
{
name: "kline ptr",
wantErr: assert.NoError,
a: &types.KLine{
Open: Number(60000),
High: Number(61000),
Low: Number(59500),
Close: Number(60100),
},
b: &types.KLine{
Open: Number(60000),
High: Number(61000),
Low: Number(59500),
Close: Number(60200),
},
want: []Diff{
{
Field: "Close",
Before: "60200",
After: "60100",
},
},
},
{
name: "deposit and order",
wantErr: assert.NoError,
Expand Down
15 changes: 15 additions & 0 deletions pkg/livenote/livenote.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,21 @@ func NewPool(size int64) *Pool {
}
}

func (p *Pool) Get(obj Object) *LiveNote {
objID := obj.ObjectID()

p.mu.Lock()
defer p.mu.Unlock()

for _, note := range p.notes {
if note.ObjectID() == objID {
return note
}
}

return nil
}

func (p *Pool) Update(obj Object) *LiveNote {
objID := obj.ObjectID()

Expand Down
83 changes: 59 additions & 24 deletions pkg/notifier/slacknotifier/slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"golang.org/x/time/rate"

"github.com/c9s/bbgo/pkg/dynamic"
"github.com/c9s/bbgo/pkg/livenote"
"github.com/c9s/bbgo/pkg/types"

Expand Down Expand Up @@ -229,50 +230,70 @@ func (n *Notifier) translateHandle(ctx context.Context, handle string) (string,
}

func (n *Notifier) PostLiveNote(obj livenote.Object, opts ...livenote.Option) error {
note := n.liveNotePool.Update(obj)
ctx := n.ctx

channel := note.ChannelID
if channel == "" {
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")
}

var slackOpts []slack.MsgOption
slackOpts = append(slackOpts, slack.MsgOptionAttachments(attachment))

var firstTimeHandles []string
var commentHandles []string
var comments []string
var shouldCompare bool
for _, opt := range opts {
switch val := opt.(type) {
case *livenote.OptionOneTimeMention:
firstTimeHandles = append(firstTimeHandles, val.Users...)
case *livenote.OptionComment:
comments = append(comments, val.Text)
commentHandles = append(commentHandles, val.Users...)
case *livenote.OptionCompare:
shouldCompare = val.Value
}
}

var ctx = n.ctx
var curObj, prevObj any
if shouldCompare {
if prevNote := n.liveNotePool.Get(obj); prevNote != nil {
prevObj = prevNote.Object
}
}

channel := n.channel
note := n.liveNotePool.Update(obj)
curObj = note.Object

if shouldCompare && prevObj != nil {
diffs, err := dynamic.Compare(curObj, prevObj)
if err != nil {
log.WithError(err).Warnf("unable to compare objects: %T and %T", curObj, prevObj)
} else {
if comment := diffsToComment(curObj, diffs); len(comment) > 0 {
comments = append(comments, comment)
}
}
}

firstTimeTags, err := n.translateHandles(context.Background(), firstTimeHandles)
if note.ChannelID != "" {
channel = note.ChannelID
}

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")
}

slackOpts = append(slackOpts, slack.MsgOptionAttachments(attachment))

firstTimeTags, err := n.translateHandles(n.ctx, firstTimeHandles)
if err != nil {
return err
}

commentTags, err := n.translateHandles(context.Background(), commentHandles)
commentTags, err := n.translateHandles(n.ctx, commentHandles)
if err != nil {
return err
}

// format: mention slack user
// <@U012AB3CD>

if note.MessageID != "" {
// If compare is enabled, we need to attach the comments

Expand Down Expand Up @@ -312,7 +333,7 @@ func (n *Notifier) PostLiveNote(obj livenote.Object, opts ...livenote.Option) er
note.SetMessageID(respTs)

if len(firstTimeTags) > 0 {
n.queueTask(context.Background(), notifyTask{
n.queueTask(n.ctx, notifyTask{
channel: respCh,
threadTs: respTs,
opts: []slack.MsgOption{
Expand All @@ -321,15 +342,15 @@ func (n *Notifier) PostLiveNote(obj livenote.Object, opts ...livenote.Option) er
},
}, 100*time.Millisecond)
}

if len(comments) > 0 {
var text string
if len(commentTags) > 0 {
text = joinTags(commentTags) + " "
}

text += joinComments(comments)
n.queueTask(context.Background(), notifyTask{
n.queueTask(n.ctx, notifyTask{
channel: respCh,
threadTs: respTs,
opts: []slack.MsgOption{
Expand Down Expand Up @@ -463,3 +484,17 @@ func joinTags(tags []string) string {
func joinComments(comments []string) string {
return strings.Join(comments, "\n")
}

func diffsToComment(obj any, diffs []dynamic.Diff) (text string) {
if len(diffs) == 0 {
return text
}

text += fmt.Sprintf("%T updated\n", obj)

for _, diff := range diffs {
text += fmt.Sprintf("- %s: `%s` transited to `%s`\n", diff.Field, diff.Before, diff.After)
}

return text
}
2 changes: 1 addition & 1 deletion pkg/strategy/example/livenote/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
log.Info(k)
bbgo.PostLiveNote(&k,
livenote.OneTimeMention(s.UserID),
livenote.Comment("please check the deposit", s.UserID),
livenote.Comment("please check the deposit"),
livenote.CompareObject(true))
}

Expand Down

0 comments on commit c289c2d

Please sign in to comment.