bbgo_origin/pkg/bbgo/bbomonitor.go

73 lines
1.5 KiB
Go

package bbgo
import (
"time"
"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types"
)
// BboMonitor monitors the best bid and ask price and volume.
//
//go:generate callbackgen -type BboMonitor
type BboMonitor struct {
Bid types.PriceVolume
Ask types.PriceVolume
UpdatedTime time.Time
priceImpactRatio fixedpoint.Value
updateCallbacks []func(bid, ask types.PriceVolume)
}
func NewBboMonitor() *BboMonitor {
return &BboMonitor{}
}
func (m *BboMonitor) SetPriceImpactRatio(ratio fixedpoint.Value) {
m.priceImpactRatio = ratio
}
func (m *BboMonitor) UpdateFromBook(book *types.StreamOrderBook) bool {
bestBid, ok1 := book.BestBid()
bestAsk, ok2 := book.BestAsk()
if !ok1 || !ok2 {
return false
}
return m.Update(bestBid, bestAsk, book.LastUpdateTime())
}
func (m *BboMonitor) Update(bid, ask types.PriceVolume, t time.Time) bool {
changed := false
if m.Bid.Price.Compare(bid.Price) != 0 || m.Bid.Volume.Compare(bid.Volume) != 0 {
if m.priceImpactRatio.IsZero() {
changed = true
} else {
if bid.Price.Sub(m.Bid.Price).Abs().Div(m.Bid.Price).Compare(m.priceImpactRatio) >= 0 {
changed = true
}
}
}
if m.Ask.Price.Compare(ask.Price) != 0 || m.Ask.Volume.Compare(ask.Volume) != 0 {
if m.priceImpactRatio.IsZero() {
changed = true
} else {
if ask.Price.Sub(m.Ask.Price).Abs().Div(m.Ask.Price).Compare(m.priceImpactRatio) >= 0 {
changed = true
}
}
}
m.Bid = bid
m.Ask = ask
m.UpdatedTime = t
if changed {
m.EmitUpdate(bid, ask)
}
return changed
}