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