Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEATURE: [livenote] object comparison, comments and mentions #1807

Merged
merged 9 commits into from
Nov 11, 2024
1 change: 1 addition & 0 deletions config/example/livenote.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ exchangeStrategies:
livenote:
symbol: BTCUSDT
interval: 5m
userID: U12345678
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
55 changes: 54 additions & 1 deletion pkg/livenote/livenote.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package livenote

import "sync"
import (
"sync"
"time"
)

type Object interface {
ObjectID() string
Expand All @@ -13,9 +16,15 @@ type LiveNote struct {

ChannelID string `json:"channelId"`

Pin bool `json:"pin"`

TimeToLive time.Duration `json:"timeToLive"`

Object Object

cachedObjID string

postedTime time.Time
}

func NewLiveNote(object Object) *LiveNote {
Expand All @@ -33,6 +42,14 @@ func (n *LiveNote) ObjectID() string {
return n.cachedObjID
}

func (n *LiveNote) SetTimeToLive(du time.Duration) {
n.TimeToLive = du
}

func (n *LiveNote) SetPostedTime(tt time.Time) {
n.postedTime = tt
}

func (n *LiveNote) SetObject(object Object) {
n.Object = object
}
Expand All @@ -45,6 +62,19 @@ func (n *LiveNote) SetChannelID(channelID string) {
n.ChannelID = channelID
}

func (n *LiveNote) SetPin(enabled bool) {
n.Pin = enabled
}

func (n *LiveNote) IsExpired(now time.Time) bool {
if n.postedTime.IsZero() || n.TimeToLive == 0 {
return false
}

expiryTime := n.postedTime.Add(n.TimeToLive)
return now.After(expiryTime)
}

type Pool struct {
notes map[string]*LiveNote
mu sync.Mutex
Expand All @@ -56,6 +86,25 @@ 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 {
if note.IsExpired(time.Now()) {
return nil
}

return note
}
}

return nil
}

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

Expand All @@ -64,6 +113,10 @@ func (p *Pool) Update(obj Object) *LiveNote {

for _, note := range p.notes {
if note.ObjectID() == objID {
if note.IsExpired(time.Now()) {
break
}

// update the object inside the note
note.SetObject(obj)
return note
Expand Down
55 changes: 52 additions & 3 deletions pkg/livenote/options.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,61 @@
package livenote

import "time"

type Option interface{}

type Mention struct {
User string
type OptionChannel struct {
Channel string
}

func Channel(channel string) *OptionChannel {
return &OptionChannel{
Channel: channel,
}
}

type OptionCompare struct {
Value bool
}

func CompareObject(value bool) *OptionCompare {
return &OptionCompare{Value: value}
}

type OptionOneTimeMention struct {
Users []string
}

func OneTimeMention(users ...string) *OptionOneTimeMention {
return &OptionOneTimeMention{Users: users}
}

type Comment struct {
type OptionComment struct {
Text string
Users []string
}

func Comment(text string, users ...string) *OptionComment {
return &OptionComment{
Text: text,
Users: users,
}
}

type OptionTimeToLive struct {
Duration time.Duration
}

func TimeToLive(du time.Duration) *OptionTimeToLive {
return &OptionTimeToLive{Duration: du}
}

type OptionPin struct {
Value bool
}

func Pin(value bool) *OptionPin {
return &OptionPin{
Value: value,
}
}
Loading
Loading