xmaker: apply margin from signal

This commit is contained in:
c9s 2024-08-30 17:39:25 +08:00
parent 371db8e7d1
commit cc820d3df0
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54
2 changed files with 65 additions and 8 deletions

View File

@ -38,9 +38,9 @@ var askMarginMetrics = prometheus.NewGaugeVec(
Help: "the current ask margin (dynamic)", Help: "the current ask margin (dynamic)",
}, []string{"strategy_type", "strategy_id", "exchange", "symbol"}) }, []string{"strategy_type", "strategy_id", "exchange", "symbol"})
var finalSignalMetrics = prometheus.NewGaugeVec( var aggregatedSignalMetrics = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "xmaker_final_signal", Name: "xmaker_aggregated_signal",
Help: "", Help: "",
}, []string{"strategy_type", "strategy_id", "exchange", "symbol"}) }, []string{"strategy_type", "strategy_id", "exchange", "symbol"})
@ -76,7 +76,7 @@ func init() {
makerBestAskPriceMetrics, makerBestAskPriceMetrics,
bidMarginMetrics, bidMarginMetrics,
askMarginMetrics, askMarginMetrics,
finalSignalMetrics, aggregatedSignalMetrics,
configNumOfLayersMetrics, configNumOfLayersMetrics,
configMaxExposureMetrics, configMaxExposureMetrics,
configBidMarginMetrics, configBidMarginMetrics,

View File

@ -85,7 +85,9 @@ type Strategy struct {
HedgeInterval types.Duration `json:"hedgeInterval"` HedgeInterval types.Duration `json:"hedgeInterval"`
OrderCancelWaitTime types.Duration `json:"orderCancelWaitTime"` OrderCancelWaitTime types.Duration `json:"orderCancelWaitTime"`
EnableSignalMargin bool `json:"enableSignalMargin"`
SignalConfigList []SignalConfig `json:"signals"` SignalConfigList []SignalConfig `json:"signals"`
SignalMarginScale *bbgo.SlideRule `json:"signalMarginScale,omitempty"`
Margin fixedpoint.Value `json:"margin"` Margin fixedpoint.Value `json:"margin"`
BidMargin fixedpoint.Value `json:"bidMargin"` BidMargin fixedpoint.Value `json:"bidMargin"`
@ -257,6 +259,39 @@ func (s *Strategy) getBollingerTrend(quote *Quote) int {
} }
} }
func (s *Strategy) applySignalMargin(ctx context.Context, quote *Quote) error {
signal, err := s.calculateSignal(ctx)
if err != nil {
return err
}
s.logger.Infof("final signal: %f", signal)
scale, err := s.SignalMarginScale.Scale()
if err != nil {
return err
}
margin := scale.Call(signal)
s.logger.Infof("signalMargin: %f", margin)
marginFp := fixedpoint.NewFromFloat(margin)
if signal < 0.0 {
quote.BidMargin = quote.BidMargin.Add(marginFp)
if signal <= -2.0 {
// quote.BidMargin = fixedpoint.Zero
}
} else if signal > 0.0 {
quote.AskMargin = quote.AskMargin.Add(marginFp)
if signal >= 2.0 {
// quote.AskMargin = fixedpoint.Zero
}
}
return nil
}
// applyBollingerMargin applies the bollinger band margin to the quote // applyBollingerMargin applies the bollinger band margin to the quote
func (s *Strategy) applyBollingerMargin( func (s *Strategy) applyBollingerMargin(
quote *Quote, quote *Quote,
@ -323,6 +358,10 @@ func (s *Strategy) calculateSignal(ctx context.Context) (float64, error) {
return 0, err return 0, err
} }
if sig == 0.0 {
continue
}
if signal.Weight > 0.0 { if signal.Weight > 0.0 {
sum += sig * signal.Weight sum += sig * signal.Weight
voters += signal.Weight voters += signal.Weight
@ -337,6 +376,10 @@ func (s *Strategy) calculateSignal(ctx context.Context) (float64, error) {
return 0, err return 0, err
} }
if sig == 0.0 {
continue
}
if signal.Weight > 0.0 { if signal.Weight > 0.0 {
sum += sig * signal.Weight sum += sig * signal.Weight
voters += signal.Weight voters += signal.Weight
@ -366,9 +409,8 @@ func (s *Strategy) updateQuote(ctx context.Context) {
return return
} }
s.logger.Infof("Final signal: %f", signal) s.logger.Infof("aggregated signal: %f", signal)
aggregatedSignalMetrics.With(s.metricsLabels).Set(signal)
finalSignalMetrics.With(s.metricsLabels).Set(signal)
if s.CircuitBreaker != nil { if s.CircuitBreaker != nil {
now := time.Now() now := time.Now()
@ -571,7 +613,12 @@ func (s *Strategy) updateQuote(ctx context.Context) {
AskLayerPips: s.Pips, AskLayerPips: s.Pips,
} }
if s.EnableBollBandMargin { if s.EnableSignalMargin {
if err := s.applySignalMargin(ctx, quote); err != nil {
s.logger.WithError(err).Errorf("unable to apply signal margin")
}
} else if s.EnableBollBandMargin {
if err := s.applyBollingerMargin(quote); err != nil { if err := s.applyBollingerMargin(quote); err != nil {
log.WithError(err).Errorf("unable to apply bollinger margin") log.WithError(err).Errorf("unable to apply bollinger margin")
} }
@ -1246,6 +1293,16 @@ func (s *Strategy) CrossRun(
s.book = types.NewStreamBook(s.Symbol, s.sourceSession.ExchangeName) s.book = types.NewStreamBook(s.Symbol, s.sourceSession.ExchangeName)
s.book.BindStream(s.sourceSession.MarketDataStream) s.book.BindStream(s.sourceSession.MarketDataStream)
if s.EnableSignalMargin {
scale, err := s.SignalMarginScale.Scale()
if err != nil {
return err
}
if solveErr := scale.Solve(); solveErr != nil {
return solveErr
}
}
for _, signalConfig := range s.SignalConfigList { for _, signalConfig := range s.SignalConfigList {
if signalConfig.OrderBookBestPriceSignal != nil { if signalConfig.OrderBookBestPriceSignal != nil {
signalConfig.OrderBookBestPriceSignal.book = s.book signalConfig.OrderBookBestPriceSignal.book = s.book