xmaker: pull out getLayerPrice and add test against the method
This commit is contained in:
parent
0e4f7b366a
commit
4d3af3a6bc
|
@ -444,6 +444,53 @@ func (s *Strategy) getInitialLayerQuantity(i int) (fixedpoint.Value, error) {
|
|||
return q, nil
|
||||
}
|
||||
|
||||
func (s *Strategy) getLayerPrice(
|
||||
i int,
|
||||
side types.SideType,
|
||||
sourceBook *types.StreamOrderBook,
|
||||
quote *Quote,
|
||||
requiredDepth fixedpoint.Value,
|
||||
) (price fixedpoint.Value) {
|
||||
var margin, delta, pips fixedpoint.Value
|
||||
|
||||
switch side {
|
||||
case types.SideTypeSell:
|
||||
margin = quote.AskMargin
|
||||
delta = margin
|
||||
|
||||
if quote.AskLayerPips.Sign() > 0 {
|
||||
pips = quote.AskLayerPips
|
||||
} else {
|
||||
pips = fixedpoint.One
|
||||
}
|
||||
|
||||
case types.SideTypeBuy:
|
||||
margin = quote.BidMargin
|
||||
delta = margin.Neg()
|
||||
|
||||
if quote.BidLayerPips.Sign() > 0 {
|
||||
pips = quote.BidLayerPips.Neg()
|
||||
} else {
|
||||
pips = fixedpoint.One.Neg()
|
||||
}
|
||||
}
|
||||
|
||||
if s.UseDepthPrice {
|
||||
price = aggregatePrice(sourceBook.SideBook(side), requiredDepth)
|
||||
price = price.Mul(fixedpoint.One.Add(delta))
|
||||
if i > 0 {
|
||||
price = price.Add(pips.Mul(s.makerMarket.TickSize))
|
||||
}
|
||||
} else {
|
||||
price = price.Mul(fixedpoint.One.Add(delta))
|
||||
if i > 0 {
|
||||
price = price.Add(pips.Mul(s.makerMarket.TickSize))
|
||||
}
|
||||
}
|
||||
|
||||
return price
|
||||
}
|
||||
|
||||
func (s *Strategy) updateQuote(ctx context.Context) error {
|
||||
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)
|
||||
|
@ -710,7 +757,6 @@ func (s *Strategy) updateQuote(ctx context.Context) error {
|
|||
|
||||
var submitOrders []types.SubmitOrder
|
||||
var accumulativeBidQuantity, accumulativeAskQuantity fixedpoint.Value
|
||||
var askQuantity = s.Quantity
|
||||
|
||||
var quote = &Quote{
|
||||
BestBidPrice: bestBidPrice,
|
||||
|
@ -798,26 +844,17 @@ func (s *Strategy) updateQuote(ctx context.Context) error {
|
|||
hedgeQuota.Rollback()
|
||||
}
|
||||
|
||||
if s.QuantityMultiplier.Sign() > 0 {
|
||||
bidQuantity = bidQuantity.Mul(s.QuantityMultiplier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < s.NumLayers; i++ {
|
||||
// for maker ask orders
|
||||
if !disableMakerAsk {
|
||||
if s.QuantityScale != nil {
|
||||
qf, err := s.QuantityScale.Scale(i + 1)
|
||||
if err != nil {
|
||||
return fmt.Errorf("quantityScale error: %w", err)
|
||||
}
|
||||
|
||||
log.Infof("%s scaling ask #%d quantity to %f", s.Symbol, i+1, qf)
|
||||
|
||||
// override the default bid quantity
|
||||
askQuantity = fixedpoint.NewFromFloat(qf)
|
||||
// for maker ask orders
|
||||
if !disableMakerAsk {
|
||||
for i := 0; i < s.NumLayers; i++ {
|
||||
askQuantity, err := s.getInitialLayerQuantity(i)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
accumulativeAskQuantity = accumulativeAskQuantity.Add(askQuantity)
|
||||
|
||||
if s.UseDepthPrice {
|
||||
|
|
|
@ -2,28 +2,87 @@ package xmaker
|
|||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.qtrade.icu/lychiyu/bbgo/pkg/fixedpoint"
|
||||
. "git.qtrade.icu/lychiyu/bbgo/pkg/testing/testhelper"
|
||||
"git.qtrade.icu/lychiyu/bbgo/pkg/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_aggregatePrice(t *testing.T) {
|
||||
bids := types.PriceVolumeSlice{
|
||||
{
|
||||
Price: fixedpoint.NewFromFloat(1000.0),
|
||||
Volume: fixedpoint.NewFromFloat(1.0),
|
||||
},
|
||||
{
|
||||
Price: fixedpoint.NewFromFloat(1200.0),
|
||||
Volume: fixedpoint.NewFromFloat(1.0),
|
||||
},
|
||||
{
|
||||
Price: fixedpoint.NewFromFloat(1400.0),
|
||||
Volume: fixedpoint.NewFromFloat(1.0),
|
||||
},
|
||||
func TestStrategy_getLayerPrice(t *testing.T) {
|
||||
symbol := "BTCUSDT"
|
||||
market := Market(symbol)
|
||||
|
||||
s := &Strategy{
|
||||
UseDepthPrice: true,
|
||||
DepthQuantity: Number(3.0),
|
||||
makerMarket: market,
|
||||
}
|
||||
|
||||
sourceBook := types.NewStreamBook(symbol, types.ExchangeBinance)
|
||||
sourceBook.Load(types.SliceOrderBook{
|
||||
Symbol: symbol,
|
||||
Bids: PriceVolumeSlice(
|
||||
Number(1300.0), Number(1.0),
|
||||
Number(1200.0), Number(2.0),
|
||||
Number(1100.0), Number(3.0),
|
||||
),
|
||||
Asks: PriceVolumeSlice(
|
||||
Number(1301.0), Number(1.0),
|
||||
Number(1400.0), Number(2.0),
|
||||
Number(1500.0), Number(3.0),
|
||||
),
|
||||
Time: time.Time{},
|
||||
LastUpdateId: 1,
|
||||
})
|
||||
|
||||
quote := &Quote{
|
||||
BestBidPrice: Number(1300.0),
|
||||
BestAskPrice: Number(1301.0),
|
||||
BidMargin: Number(0.001),
|
||||
AskMargin: Number(0.001),
|
||||
BidLayerPips: Number(100.0),
|
||||
AskLayerPips: Number(100.0),
|
||||
}
|
||||
|
||||
t.Run("depthPrice bid price at 0", func(t *testing.T) {
|
||||
price := s.getLayerPrice(0, types.SideTypeBuy, sourceBook, quote, s.DepthQuantity)
|
||||
|
||||
// (1300 + 1200*2)/3 * (1 - 0.001)
|
||||
assert.InDelta(t, 1232.10, price.Float64(), 0.01)
|
||||
})
|
||||
|
||||
t.Run("depthPrice bid price at 1", func(t *testing.T) {
|
||||
price := s.getLayerPrice(1, types.SideTypeBuy, sourceBook, quote, s.DepthQuantity)
|
||||
|
||||
// (1300 + 1200*2)/3 * (1 - 0.001) - 100 * 0.01
|
||||
assert.InDelta(t, 1231.10, price.Float64(), 0.01)
|
||||
})
|
||||
|
||||
t.Run("depthPrice ask price at 0", func(t *testing.T) {
|
||||
price := s.getLayerPrice(0, types.SideTypeSell, sourceBook, quote, s.DepthQuantity)
|
||||
|
||||
// (1301 + 1400*2)/3 * (1 + 0.001)
|
||||
assert.InDelta(t, 1368.367, price.Float64(), 0.01)
|
||||
})
|
||||
|
||||
t.Run("depthPrice ask price at 1", func(t *testing.T) {
|
||||
price := s.getLayerPrice(1, types.SideTypeSell, sourceBook, quote, s.DepthQuantity)
|
||||
|
||||
// (1301 + 1400*2)/3 * (1 + 0.001) + 100 * 0.01
|
||||
assert.InDelta(t, 1369.367, price.Float64(), 0.01)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func Test_aggregatePrice(t *testing.T) {
|
||||
bids := PriceVolumeSliceFromText(`
|
||||
1000.0, 1.0
|
||||
1200.0, 1.0
|
||||
1400.0, 1.0
|
||||
`)
|
||||
|
||||
aggregatedPrice1 := aggregatePrice(bids, fixedpoint.NewFromFloat(0.5))
|
||||
assert.Equal(t, fixedpoint.NewFromFloat(1000.0), aggregatedPrice1)
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user