improve price hart beat usage

This commit is contained in:
c9s 2023-11-30 13:44:35 +08:00
parent 46b3a81b07
commit e0e9876902
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54
4 changed files with 42 additions and 23 deletions

View File

@ -230,7 +230,7 @@ type Strategy struct {
hedgeErrorLimiter *rate.Limiter hedgeErrorLimiter *rate.Limiter
hedgeErrorRateReservation *rate.Reservation hedgeErrorRateReservation *rate.Reservation
askPriceHeartBeat, bidPriceHeartBeat types.PriceHeartBeat askPriceHeartBeat, bidPriceHeartBeat *types.PriceHeartBeat
lastPrice fixedpoint.Value lastPrice fixedpoint.Value
@ -318,6 +318,8 @@ func (s *Strategy) Defaults() error {
} }
func (s *Strategy) Initialize() error { func (s *Strategy) Initialize() error {
s.bidPriceHeartBeat = types.NewPriceHeartBeat(priceUpdateTimeout)
s.askPriceHeartBeat = types.NewPriceHeartBeat(priceUpdateTimeout)
return nil return nil
} }
@ -701,14 +703,14 @@ func (s *Strategy) updateQuote(ctx context.Context) {
bookLastUpdateTime := s.pricingBook.LastUpdateTime() bookLastUpdateTime := s.pricingBook.LastUpdateTime()
if _, err := s.bidPriceHeartBeat.Update(bestBid, priceUpdateTimeout); err != nil { if _, err := s.bidPriceHeartBeat.Update(bestBid); err != nil {
log.WithError(err).Errorf("quote update error, %s price not updating, order book last update: %s ago", log.WithError(err).Errorf("quote update error, %s price not updating, order book last update: %s ago",
s.Symbol, s.Symbol,
time.Since(bookLastUpdateTime)) time.Since(bookLastUpdateTime))
return return
} }
if _, err := s.askPriceHeartBeat.Update(bestAsk, priceUpdateTimeout); err != nil { if _, err := s.askPriceHeartBeat.Update(bestAsk); err != nil {
log.WithError(err).Errorf("quote update error, %s price not updating, order book last update: %s ago", log.WithError(err).Errorf("quote update error, %s price not updating, order book last update: %s ago",
s.Symbol, s.Symbol,
time.Since(bookLastUpdateTime)) time.Since(bookLastUpdateTime))

View File

@ -112,7 +112,7 @@ type Strategy struct {
orderStore *core.OrderStore orderStore *core.OrderStore
tradeCollector *core.TradeCollector tradeCollector *core.TradeCollector
askPriceHeartBeat, bidPriceHeartBeat types.PriceHeartBeat askPriceHeartBeat, bidPriceHeartBeat *types.PriceHeartBeat
lastPrice fixedpoint.Value lastPrice fixedpoint.Value
groupID uint32 groupID uint32
@ -170,6 +170,12 @@ func aggregatePrice(pvs types.PriceVolumeSlice, requiredQuantity fixedpoint.Valu
return price return price
} }
func (s *Strategy) Initialize() error {
s.bidPriceHeartBeat = types.NewPriceHeartBeat(priceUpdateTimeout)
s.askPriceHeartBeat = types.NewPriceHeartBeat(priceUpdateTimeout)
return nil
}
func (s *Strategy) updateQuote(ctx context.Context, orderExecutionRouter bbgo.OrderExecutionRouter) { func (s *Strategy) updateQuote(ctx context.Context, orderExecutionRouter bbgo.OrderExecutionRouter) {
if err := s.activeMakerOrders.GracefulCancel(ctx, s.makerSession.Exchange); err != nil { if err := s.activeMakerOrders.GracefulCancel(ctx, s.makerSession.Exchange); err != nil {
log.Warnf("there are some %s orders not canceled, skipping placing maker orders", s.Symbol) log.Warnf("there are some %s orders not canceled, skipping placing maker orders", s.Symbol)
@ -191,14 +197,14 @@ func (s *Strategy) updateQuote(ctx context.Context, orderExecutionRouter bbgo.Or
bookLastUpdateTime := s.book.LastUpdateTime() bookLastUpdateTime := s.book.LastUpdateTime()
if _, err := s.bidPriceHeartBeat.Update(bestBid, priceUpdateTimeout); err != nil { if _, err := s.bidPriceHeartBeat.Update(bestBid); err != nil {
log.WithError(err).Errorf("quote update error, %s price not updating, order book last update: %s ago", log.WithError(err).Errorf("quote update error, %s price not updating, order book last update: %s ago",
s.Symbol, s.Symbol,
time.Since(bookLastUpdateTime)) time.Since(bookLastUpdateTime))
return return
} }
if _, err := s.askPriceHeartBeat.Update(bestAsk, priceUpdateTimeout); err != nil { if _, err := s.askPriceHeartBeat.Update(bestAsk); err != nil {
log.WithError(err).Errorf("quote update error, %s price not updating, order book last update: %s ago", log.WithError(err).Errorf("quote update error, %s price not updating, order book last update: %s ago",
s.Symbol, s.Symbol,
time.Since(bookLastUpdateTime)) time.Since(bookLastUpdateTime))
@ -639,7 +645,9 @@ func (s *Strategy) Validate() error {
return nil return nil
} }
func (s *Strategy) CrossRun(ctx context.Context, orderExecutionRouter bbgo.OrderExecutionRouter, sessions map[string]*bbgo.ExchangeSession) error { func (s *Strategy) CrossRun(
ctx context.Context, orderExecutionRouter bbgo.OrderExecutionRouter, sessions map[string]*bbgo.ExchangeSession,
) error {
if s.BollBandInterval == "" { if s.BollBandInterval == "" {
s.BollBandInterval = types.Interval1m s.BollBandInterval = types.Interval1m
} }

View File

@ -7,24 +7,34 @@ import (
// PriceHeartBeat is used for monitoring the price volume update. // PriceHeartBeat is used for monitoring the price volume update.
type PriceHeartBeat struct { type PriceHeartBeat struct {
PriceVolume PriceVolume last PriceVolume
LastTime time.Time lastUpdatedTime time.Time
timeout time.Duration
}
func NewPriceHeartBeat(timeout time.Duration) *PriceHeartBeat {
return &PriceHeartBeat{
timeout: timeout,
}
} }
// Update updates the price volume object and the last update time // Update updates the price volume object and the last update time
// It returns (bool, error), when the price is successfully updated, it returns true. // It returns (bool, error), when the price is successfully updated, it returns true.
// If the price is not updated (same price) and the last time exceeded the timeout, // If the price is not updated (same price) and the last time exceeded the timeout,
// Then false, and an error will be returned // Then false, and an error will be returned
func (b *PriceHeartBeat) Update(pv PriceVolume, timeout time.Duration) (bool, error) { func (b *PriceHeartBeat) Update(current PriceVolume) (bool, error) {
if b.PriceVolume.Price.IsZero() || b.PriceVolume != pv { if b.last.Price.IsZero() || b.last != current {
b.PriceVolume = pv b.last = current
b.LastTime = time.Now() b.lastUpdatedTime = time.Now()
return true, nil // successfully updated return true, nil // successfully updated
} else if time.Since(b.LastTime) > timeout { } else {
return false, fmt.Errorf("price %s has not been updating for %s, last update: %s, skip quoting", // if price and volume is not changed
b.PriceVolume.String(), if b.last.Equals(current) && time.Since(b.lastUpdatedTime) > b.timeout {
time.Since(b.LastTime), return false, fmt.Errorf("price %s has not been updating for %s, last update: %s, skip quoting",
b.LastTime) b.last.String(),
time.Since(b.lastUpdatedTime),
b.lastUpdatedTime)
}
} }
return false, nil return false, nil

View File

@ -2,7 +2,6 @@ package types
import ( import (
"testing" "testing"
"time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -11,19 +10,19 @@ import (
func TestPriceHeartBeat_Update(t *testing.T) { func TestPriceHeartBeat_Update(t *testing.T) {
hb := PriceHeartBeat{} hb := PriceHeartBeat{}
updated, err := hb.Update(PriceVolume{Price: fixedpoint.NewFromFloat(22.0), Volume: fixedpoint.NewFromFloat(100.0)}, time.Minute) updated, err := hb.Update(PriceVolume{Price: fixedpoint.NewFromFloat(22.0), Volume: fixedpoint.NewFromFloat(100.0)})
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, updated) assert.True(t, updated)
updated, err = hb.Update(PriceVolume{Price: fixedpoint.NewFromFloat(22.0), Volume: fixedpoint.NewFromFloat(100.0)}, time.Minute) updated, err = hb.Update(PriceVolume{Price: fixedpoint.NewFromFloat(22.0), Volume: fixedpoint.NewFromFloat(100.0)})
assert.NoError(t, err) assert.NoError(t, err)
assert.False(t, updated, "should not be updated when pv is not changed") assert.False(t, updated, "should not be updated when pv is not changed")
updated, err = hb.Update(PriceVolume{Price: fixedpoint.NewFromFloat(23.0), Volume: fixedpoint.NewFromFloat(100.0)}, time.Minute) updated, err = hb.Update(PriceVolume{Price: fixedpoint.NewFromFloat(23.0), Volume: fixedpoint.NewFromFloat(100.0)})
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, updated, "should be updated when the price is changed") assert.True(t, updated, "should be updated when the price is changed")
updated, err = hb.Update(PriceVolume{Price: fixedpoint.NewFromFloat(23.0), Volume: fixedpoint.NewFromFloat(200.0)}, time.Minute) updated, err = hb.Update(PriceVolume{Price: fixedpoint.NewFromFloat(23.0), Volume: fixedpoint.NewFromFloat(200.0)})
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, updated, "should be updated when the volume is changed") assert.True(t, updated, "should be updated when the volume is changed")
} }