bbgo_origin/pkg/strategy/xmaker/signal_depth.go
2024-09-30 16:21:22 +08:00

81 lines
2.0 KiB
Go

package xmaker
import (
"context"
"math"
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types"
)
var depthRatioSignalMetrics = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "xmaker_depth_ratio_signal",
Help: "",
}, []string{"symbol"})
func init() {
prometheus.MustRegister(depthRatioSignalMetrics)
}
type DepthRatioSignal struct {
// PriceRange, 2% depth ratio means 2% price range from the mid price
PriceRange fixedpoint.Value `json:"priceRange"`
MinRatio float64 `json:"minRatio"`
symbol string
book *types.StreamOrderBook
}
func (s *DepthRatioSignal) BindStreamBook(book *types.StreamOrderBook) {
s.book = book
}
func (s *DepthRatioSignal) Bind(ctx context.Context, session *bbgo.ExchangeSession, symbol string) error {
if s.book == nil {
return errors.New("s.book can not be nil")
}
s.symbol = symbol
orderBookSignalMetrics.WithLabelValues(s.symbol).Set(0.0)
return nil
}
func (s *DepthRatioSignal) CalculateSignal(ctx context.Context) (float64, error) {
bid, ask, ok := s.book.BestBidAndAsk()
if !ok {
return 0.0, nil
}
midPrice := bid.Price.Add(ask.Price).Div(fixedpoint.Two)
asks := s.book.SideBook(types.SideTypeSell)
bids := s.book.SideBook(types.SideTypeBuy)
asksInRange := asks.InPriceRange(midPrice, types.SideTypeSell, s.PriceRange)
bidsInRange := bids.InPriceRange(midPrice, types.SideTypeBuy, s.PriceRange)
askDepthQuote := asksInRange.SumDepthInQuote()
bidDepthQuote := bidsInRange.SumDepthInQuote()
var signal = 0.0
depthRatio := bidDepthQuote.Div(askDepthQuote.Add(bidDepthQuote))
// convert ratio into -2.0 and 2.0
signal = depthRatio.Sub(fixedpoint.NewFromFloat(0.5)).Float64() * 4.0
// ignore noise
if math.Abs(signal) < s.MinRatio {
signal = 0.0
}
log.Infof("[DepthRatioSignal] %f bid/ask = %f/%f", signal, bidDepthQuote.Float64(), askDepthQuote.Float64())
depthRatioSignalMetrics.WithLabelValues(s.symbol).Set(signal)
return signal, nil
}