diff --git a/pkg/bbgo/trade_store.go b/pkg/bbgo/trade_store.go index a19c63f2d..605631868 100644 --- a/pkg/bbgo/trade_store.go +++ b/pkg/bbgo/trade_store.go @@ -8,12 +8,14 @@ import ( ) const TradeExpiryTime = 24 * time.Hour +const PruneTriggerNumOfTrades = 10_000 type TradeStore struct { // any created trades for tracking trades sync.Mutex - trades map[uint64]types.Trade + trades map[uint64]types.Trade + lastTradeTime time.Time } func NewTradeStore() *TradeStore { @@ -96,6 +98,13 @@ func (s *TradeStore) Add(trades ...types.Trade) { for _, trade := range trades { s.trades[trade.ID] = trade + s.touchLastTradeTime(trade) + } +} + +func (s *TradeStore) touchLastTradeTime(trade types.Trade) { + if trade.Time.Time().After(s.lastTradeTime) { + s.lastTradeTime = trade.Time.Time() } } @@ -122,8 +131,16 @@ func (s *TradeStore) Prune(curTime time.Time) { s.pruneExpiredTrades(curTime) } +func (s *TradeStore) isCoolTrade(trade types.Trade) bool { + // if the time of last trade is over 1 hour, we call it's cool trade + return s.lastTradeTime != (time.Time{}) && time.Time(trade.Time).Sub(s.lastTradeTime) > time.Hour +} + func (s *TradeStore) BindStream(stream types.Stream) { stream.OnTradeUpdate(func(trade types.Trade) { s.Add(trade) + if s.isCoolTrade(trade) { + s.Prune(time.Time(trade.Time)) + } }) } diff --git a/pkg/bbgo/trade_store_test.go b/pkg/bbgo/trade_store_test.go new file mode 100644 index 000000000..f3a5a1ed9 --- /dev/null +++ b/pkg/bbgo/trade_store_test.go @@ -0,0 +1,39 @@ +package bbgo + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + + "github.com/c9s/bbgo/pkg/types" +) + +func TestTradeStore_isCoolTrade(t *testing.T) { + now := time.Now() + store := NewTradeStore() + store.lastTradeTime = now.Add(-2 * time.Hour) + ok := store.isCoolTrade(types.Trade{ + Time: types.Time(now), + }) + assert.True(t, ok) + + store.lastTradeTime = now.Add(-2 * time.Minute) + ok = store.isCoolTrade(types.Trade{ + Time: types.Time(now), + }) + assert.False(t, ok) +} + +func TestTradeStore_Prune(t *testing.T) { + now := time.Now() + store := NewTradeStore() + store.Add( + types.Trade{ID: 1, Time: types.Time(now.Add(-25 * time.Hour))}, + types.Trade{ID: 2, Time: types.Time(now.Add(-23 * time.Hour))}, + types.Trade{ID: 3, Time: types.Time(now.Add(-2 * time.Minute))}, + types.Trade{ID: 4, Time: types.Time(now.Add(-1 * time.Minute))}, + ) + store.Prune(now) + assert.Equal(t, 3, len(store.trades)) +}