mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-22 06:53:52 +00:00
xdepthmaker: add priceImpactRatio detection
This commit is contained in:
parent
be353c533b
commit
4661ec629d
|
@ -3,6 +3,7 @@ package bbgo
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
|
@ -14,6 +15,8 @@ type BboMonitor struct {
|
|||
Ask types.PriceVolume
|
||||
UpdatedTime time.Time
|
||||
|
||||
priceImpactRatio fixedpoint.Value
|
||||
|
||||
updateCallbacks []func(bid, ask types.PriceVolume)
|
||||
}
|
||||
|
||||
|
@ -21,6 +24,10 @@ 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()
|
||||
|
@ -34,11 +41,23 @@ func (m *BboMonitor) UpdateFromBook(book *types.StreamOrderBook) bool {
|
|||
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
|
||||
|
|
|
@ -210,8 +210,8 @@ type Strategy struct {
|
|||
// HedgeExchange session name
|
||||
HedgeExchange string `json:"hedgeExchange"`
|
||||
|
||||
UpdateInterval types.Duration `json:"updateInterval"`
|
||||
UpdateLayers int `json:"updateLayers"`
|
||||
FastLayerUpdateInterval types.Duration `json:"fastLayerUpdateInterval"`
|
||||
NumOfFastLayers int `json:"numOfFastLayers"`
|
||||
|
||||
HedgeInterval types.Duration `json:"hedgeInterval"`
|
||||
|
||||
|
@ -249,6 +249,8 @@ type Strategy struct {
|
|||
// RecoverTrade tries to find the missing trades via the REStful API
|
||||
RecoverTrade bool `json:"recoverTrade"`
|
||||
|
||||
PriceImpactRatio fixedpoint.Value `json:"priceImpactRatio"`
|
||||
|
||||
RecoverTradeScanPeriod types.Duration `json:"recoverTradeScanPeriod"`
|
||||
|
||||
NumLayers int `json:"numLayers"`
|
||||
|
@ -281,6 +283,7 @@ type Strategy struct {
|
|||
connectivityGroup *types.ConnectivityGroup
|
||||
|
||||
priceSolver *pricesolver.SimplePriceSolver
|
||||
bboMonitor *bbgo.BboMonitor
|
||||
}
|
||||
|
||||
func (s *Strategy) ID() string {
|
||||
|
@ -353,12 +356,12 @@ func (s *Strategy) Validate() error {
|
|||
}
|
||||
|
||||
func (s *Strategy) Defaults() error {
|
||||
if s.UpdateInterval == 0 {
|
||||
s.UpdateInterval = types.Duration(5 * time.Second)
|
||||
if s.FastLayerUpdateInterval == 0 {
|
||||
s.FastLayerUpdateInterval = types.Duration(5 * time.Second)
|
||||
}
|
||||
|
||||
if s.UpdateLayers == 0 {
|
||||
s.UpdateLayers = 5
|
||||
if s.NumOfFastLayers == 0 {
|
||||
s.NumOfFastLayers = 5
|
||||
}
|
||||
|
||||
if s.FullReplenishInterval == 0 {
|
||||
|
@ -406,8 +409,7 @@ func (s *Strategy) Defaults() error {
|
|||
}
|
||||
|
||||
func (s *Strategy) quoteWorker(ctx context.Context) {
|
||||
|
||||
updateTicker := time.NewTicker(util.MillisecondsJitter(s.UpdateInterval.Duration(), 200))
|
||||
updateTicker := time.NewTicker(util.MillisecondsJitter(s.FastLayerUpdateInterval.Duration(), 200))
|
||||
defer updateTicker.Stop()
|
||||
|
||||
fullReplenishTicker := time.NewTicker(util.MillisecondsJitter(s.FullReplenishInterval.Duration(), 200))
|
||||
|
@ -421,8 +423,6 @@ func (s *Strategy) quoteWorker(ctx context.Context) {
|
|||
|
||||
s.updateQuote(ctx, 0)
|
||||
|
||||
lastOrderReplenishTime := time.Now()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
|
@ -438,7 +438,9 @@ func (s *Strategy) quoteWorker(ctx context.Context) {
|
|||
|
||||
case <-fullReplenishTicker.C:
|
||||
s.updateQuote(ctx, 0)
|
||||
lastOrderReplenishTime = time.Now()
|
||||
|
||||
case <-updateTicker.C:
|
||||
s.updateQuote(ctx, s.NumOfFastLayers)
|
||||
|
||||
case sig, ok := <-s.sourceBook.C:
|
||||
// when any book change event happened
|
||||
|
@ -446,19 +448,10 @@ func (s *Strategy) quoteWorker(ctx context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
if time.Since(lastOrderReplenishTime) < 10*time.Second {
|
||||
continue
|
||||
}
|
||||
|
||||
switch sig.Type {
|
||||
case types.BookSignalSnapshot:
|
||||
changed := s.bboMonitor.UpdateFromBook(s.sourceBook)
|
||||
if changed || sig.Type == types.BookSignalSnapshot {
|
||||
s.updateQuote(ctx, 0)
|
||||
|
||||
case types.BookSignalUpdate:
|
||||
s.updateQuote(ctx, s.UpdateLayers)
|
||||
}
|
||||
|
||||
lastOrderReplenishTime = time.Now()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -584,6 +577,11 @@ func (s *Strategy) CrossRun(
|
|||
s.priceSolver.BindStream(s.hedgeSession.MarketDataStream)
|
||||
s.priceSolver.BindStream(s.makerSession.MarketDataStream)
|
||||
|
||||
s.bboMonitor = bbgo.NewBboMonitor()
|
||||
if !s.PriceImpactRatio.IsZero() {
|
||||
s.bboMonitor.SetPriceImpactRatio(s.PriceImpactRatio)
|
||||
}
|
||||
|
||||
if err := s.priceSolver.UpdateFromTickers(ctx, s.makerSession.Exchange,
|
||||
s.Symbol, s.makerSession.Exchange.PlatformFeeCurrency()+"USDT"); err != nil {
|
||||
return err
|
||||
|
@ -640,7 +638,7 @@ func (s *Strategy) CrossRun(
|
|||
close(s.stopC)
|
||||
|
||||
// wait for the quoter to stop
|
||||
time.Sleep(s.UpdateInterval.Duration())
|
||||
time.Sleep(s.FastLayerUpdateInterval.Duration())
|
||||
|
||||
if err := s.MakerOrderExecutor.GracefulCancel(ctx); err != nil {
|
||||
log.WithError(err).Errorf("graceful cancel %s order error", s.Symbol)
|
||||
|
|
Loading…
Reference in New Issue
Block a user