xmaker: refactor getInitialLayerQuantity for quantity multiplier
This commit is contained in:
parent
bb525c72f7
commit
1d71e5c80a
|
@ -417,21 +417,48 @@ func (s *Strategy) aggregateSignal(ctx context.Context) (float64, error) {
|
||||||
return sum / voters, nil
|
return sum / voters, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Strategy) updateQuote(ctx context.Context) {
|
// getInitialLayerQuantity returns the initial quantity for the layer
|
||||||
|
// i is the layer index, starting from 0
|
||||||
|
func (s *Strategy) getInitialLayerQuantity(i int) (fixedpoint.Value, error) {
|
||||||
|
if s.QuantityScale != nil {
|
||||||
|
qf, err := s.QuantityScale.Scale(i + 1)
|
||||||
|
if err != nil {
|
||||||
|
return fixedpoint.Zero, fmt.Errorf("quantityScale error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("%s scaling bid #%d quantity to %f", s.Symbol, i+1, qf)
|
||||||
|
|
||||||
|
// override the default quantity
|
||||||
|
return fixedpoint.NewFromFloat(qf), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
q := s.Quantity
|
||||||
|
|
||||||
|
if s.QuantityMultiplier.Sign() > 0 && i > 0 {
|
||||||
|
q = fixedpoint.NewFromFloat(
|
||||||
|
q.Float64() * math.Pow(
|
||||||
|
s.QuantityMultiplier.Float64(), float64(i+1)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback to the fixed quantity
|
||||||
|
return q, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Strategy) updateQuote(ctx context.Context) error {
|
||||||
if err := s.activeMakerOrders.GracefulCancel(ctx, s.makerSession.Exchange); err != nil {
|
if err := s.activeMakerOrders.GracefulCancel(ctx, s.makerSession.Exchange); err != nil {
|
||||||
s.logger.Warnf("there are some %s orders not canceled, skipping placing maker orders", s.Symbol)
|
s.logger.Warnf("there are some %s orders not canceled, skipping placing maker orders", s.Symbol)
|
||||||
s.activeMakerOrders.Print()
|
s.activeMakerOrders.Print()
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.activeMakerOrders.NumOfOrders() > 0 {
|
if s.activeMakerOrders.NumOfOrders() > 0 {
|
||||||
s.logger.Warnf("unable to cancel all %s orders, skipping placing maker orders", s.Symbol)
|
s.logger.Warnf("unable to cancel all %s orders, skipping placing maker orders", s.Symbol)
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
signal, err := s.aggregateSignal(ctx)
|
signal, err := s.aggregateSignal(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.logger.Infof("aggregated signal: %f", signal)
|
s.logger.Infof("aggregated signal: %f", signal)
|
||||||
|
@ -446,14 +473,14 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
||||||
bbgo.Notify("Strategy %s is halted, reason: %s", ID, reason)
|
bbgo.Notify("Strategy %s is halted, reason: %s", ID, reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bestBid, bestAsk, hasPrice := s.sourceBook.BestBidAndAsk()
|
bestBid, bestAsk, hasPrice := s.sourceBook.BestBidAndAsk()
|
||||||
if !hasPrice {
|
if !hasPrice {
|
||||||
s.logger.Warnf("no valid price, skip quoting")
|
s.logger.Warnf("no valid price, skip quoting")
|
||||||
return
|
return fmt.Errorf("no valid book price")
|
||||||
}
|
}
|
||||||
|
|
||||||
bestBidPrice := bestBid.Price
|
bestBidPrice := bestBid.Price
|
||||||
|
@ -461,11 +488,10 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
||||||
s.logger.Infof("%s book ticker: best ask / best bid = %v / %v", s.Symbol, bestAskPrice, bestBidPrice)
|
s.logger.Infof("%s book ticker: best ask / best bid = %v / %v", s.Symbol, bestAskPrice, bestBidPrice)
|
||||||
|
|
||||||
if bestBidPrice.Compare(bestAskPrice) > 0 {
|
if bestBidPrice.Compare(bestAskPrice) > 0 {
|
||||||
log.Errorf("best bid price %f is higher than best ask price %f, skip quoting",
|
return fmt.Errorf("best bid price %f is higher than best ask price %f, skip quoting",
|
||||||
bestBidPrice.Float64(),
|
bestBidPrice.Float64(),
|
||||||
bestAskPrice.Float64(),
|
bestAskPrice.Float64(),
|
||||||
)
|
)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.EnableArbitrage {
|
if s.EnableArbitrage {
|
||||||
|
@ -495,20 +521,20 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
||||||
s.logger.WithError(err).Errorf("quote update error, %s price not updating, order book last update: %s ago",
|
s.logger.WithError(err).Errorf("quote update error, %s price not updating, order book last update: %s ago",
|
||||||
s.Symbol,
|
s.Symbol,
|
||||||
time.Since(bookLastUpdateTime))
|
time.Since(bookLastUpdateTime))
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := s.askPriceHeartBeat.Update(bestAsk); err != nil {
|
if _, err := s.askPriceHeartBeat.Update(bestAsk); err != nil {
|
||||||
s.logger.WithError(err).Errorf("quote update error, %s price not updating, order book last update: %s ago",
|
s.logger.WithError(err).Errorf("quote update error, %s price not updating, order book last update: %s ago",
|
||||||
s.Symbol,
|
s.Symbol,
|
||||||
time.Since(bookLastUpdateTime))
|
time.Since(bookLastUpdateTime))
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceBook := s.sourceBook.CopyDepth(10)
|
sourceBook := s.sourceBook.CopyDepth(10)
|
||||||
if valid, err := sourceBook.IsValid(); !valid {
|
if valid, err := sourceBook.IsValid(); !valid {
|
||||||
s.logger.WithError(err).Errorf("%s invalid copied order book, skip quoting: %v", s.Symbol, err)
|
s.logger.WithError(err).Errorf("%s invalid copied order book, skip quoting: %v", s.Symbol, err)
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var disableMakerBid = false
|
var disableMakerBid = false
|
||||||
|
@ -679,12 +705,11 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
||||||
|
|
||||||
if disableMakerAsk && disableMakerBid {
|
if disableMakerAsk && disableMakerBid {
|
||||||
log.Warnf("%s bid/ask maker is disabled due to insufficient balances", s.Symbol)
|
log.Warnf("%s bid/ask maker is disabled due to insufficient balances", s.Symbol)
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var submitOrders []types.SubmitOrder
|
var submitOrders []types.SubmitOrder
|
||||||
var accumulativeBidQuantity, accumulativeAskQuantity fixedpoint.Value
|
var accumulativeBidQuantity, accumulativeAskQuantity fixedpoint.Value
|
||||||
var bidQuantity = s.Quantity
|
|
||||||
var askQuantity = s.Quantity
|
var askQuantity = s.Quantity
|
||||||
|
|
||||||
var quote = &Quote{
|
var quote = &Quote{
|
||||||
|
@ -715,22 +740,14 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
||||||
bidMarginMetrics.With(s.metricsLabels).Set(quote.BidMargin.Float64())
|
bidMarginMetrics.With(s.metricsLabels).Set(quote.BidMargin.Float64())
|
||||||
askMarginMetrics.With(s.metricsLabels).Set(quote.AskMargin.Float64())
|
askMarginMetrics.With(s.metricsLabels).Set(quote.AskMargin.Float64())
|
||||||
|
|
||||||
for i := 0; i < s.NumLayers; i++ {
|
if !disableMakerBid {
|
||||||
// for maker bid orders
|
for i := 0; i < s.NumLayers; i++ {
|
||||||
if !disableMakerBid {
|
bidQuantity, err := s.getInitialLayerQuantity(i)
|
||||||
if s.QuantityScale != nil {
|
if err != nil {
|
||||||
qf, err := s.QuantityScale.Scale(i + 1)
|
return err
|
||||||
if err != nil {
|
|
||||||
log.WithError(err).Errorf("quantityScale error")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Infof("%s scaling bid #%d quantity to %f", s.Symbol, i+1, qf)
|
|
||||||
|
|
||||||
// override the default bid quantity
|
|
||||||
bidQuantity = fixedpoint.NewFromFloat(qf)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for maker bid orders
|
||||||
accumulativeBidQuantity = accumulativeBidQuantity.Add(bidQuantity)
|
accumulativeBidQuantity = accumulativeBidQuantity.Add(bidQuantity)
|
||||||
|
|
||||||
if s.UseDepthPrice {
|
if s.UseDepthPrice {
|
||||||
|
@ -785,14 +802,15 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
||||||
bidQuantity = bidQuantity.Mul(s.QuantityMultiplier)
|
bidQuantity = bidQuantity.Mul(s.QuantityMultiplier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < s.NumLayers; i++ {
|
||||||
// for maker ask orders
|
// for maker ask orders
|
||||||
if !disableMakerAsk {
|
if !disableMakerAsk {
|
||||||
if s.QuantityScale != nil {
|
if s.QuantityScale != nil {
|
||||||
qf, err := s.QuantityScale.Scale(i + 1)
|
qf, err := s.QuantityScale.Scale(i + 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Errorf("quantityScale error")
|
return fmt.Errorf("quantityScale error: %w", err)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("%s scaling ask #%d quantity to %f", s.Symbol, i+1, qf)
|
log.Infof("%s scaling ask #%d quantity to %f", s.Symbol, i+1, qf)
|
||||||
|
@ -859,12 +877,12 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
||||||
|
|
||||||
if len(submitOrders) == 0 {
|
if len(submitOrders) == 0 {
|
||||||
log.Warnf("no orders generated")
|
log.Warnf("no orders generated")
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
formattedOrders, err := s.makerSession.FormatOrders(submitOrders)
|
formattedOrders, err := s.makerSession.FormatOrders(submitOrders)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
orderCreateCallback := func(createdOrder types.Order) {
|
orderCreateCallback := func(createdOrder types.Order) {
|
||||||
|
@ -877,7 +895,7 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
||||||
createdOrders, errIdx, err := bbgo.BatchPlaceOrder(ctx, s.makerSession.Exchange, orderCreateCallback, formattedOrders...)
|
createdOrders, errIdx, err := bbgo.BatchPlaceOrder(ctx, s.makerSession.Exchange, orderCreateCallback, formattedOrders...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Errorf("unable to place maker orders: %+v", formattedOrders)
|
log.WithError(err).Errorf("unable to place maker orders: %+v", formattedOrders)
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
openOrderBidExposureInUsdMetrics.With(s.metricsLabels).Set(bidExposureInUsd.Float64())
|
openOrderBidExposureInUsdMetrics.With(s.metricsLabels).Set(bidExposureInUsd.Float64())
|
||||||
|
@ -885,6 +903,7 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
||||||
|
|
||||||
_ = errIdx
|
_ = errIdx
|
||||||
_ = createdOrders
|
_ = createdOrders
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Strategy) adjustHedgeQuantityWithAvailableBalance(
|
func (s *Strategy) adjustHedgeQuantityWithAvailableBalance(
|
||||||
|
|
Loading…
Reference in New Issue
Block a user