mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
calculate price by depth
This commit is contained in:
parent
4429a29c29
commit
b86ed36aa2
|
@ -118,9 +118,30 @@ func (s *Strategy) CrossSubscribe(sessions map[string]*bbgo.ExchangeSession) {
|
|||
makerSession.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: "1m"})
|
||||
}
|
||||
|
||||
func aggregatePrice(quantity fixedpoint.Value) (price fixedpoint.Value) {
|
||||
func aggregatePrice(pvs types.PriceVolumeSlice, requiredQuantity fixedpoint.Value) (price fixedpoint.Value) {
|
||||
q := requiredQuantity
|
||||
totalAmount := fixedpoint.Value(0)
|
||||
|
||||
return
|
||||
if len(pvs) == 0 {
|
||||
price = 0
|
||||
return price
|
||||
} else if pvs[0].Volume >= requiredQuantity {
|
||||
return pvs[0].Price
|
||||
}
|
||||
|
||||
for i := 0; i < len(pvs); i++ {
|
||||
pv := pvs[i]
|
||||
if pv.Volume >= q {
|
||||
totalAmount += q.Mul(pv.Price)
|
||||
break
|
||||
}
|
||||
|
||||
q -= pv.Volume
|
||||
totalAmount += pv.Volume.Mul(pv.Price)
|
||||
}
|
||||
|
||||
price = totalAmount.Div(requiredQuantity)
|
||||
return price
|
||||
}
|
||||
|
||||
func (s *Strategy) updateQuote(ctx context.Context) {
|
||||
|
@ -218,55 +239,12 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
var totalBidQuantity, totalAskQuantity fixedpoint.Value
|
||||
|
||||
// askQuantity and bidQuantity could be different, so we are doing it twice
|
||||
for i := 0; i < s.NumLayers; i++ {
|
||||
askQuantity := s.Quantity
|
||||
bidQuantity := s.Quantity
|
||||
|
||||
if !disableMakerBid {
|
||||
if s.QuantityScale != nil {
|
||||
qf, err := s.QuantityScale.Scale(i + 1)
|
||||
if err != nil {
|
||||
log.WithError(err).Errorf("quantityScale error")
|
||||
return
|
||||
}
|
||||
|
||||
log.Infof("scaling quantity to %f by layer: %d", qf, i+1)
|
||||
|
||||
// override the default bid quantity
|
||||
bidQuantity = fixedpoint.NewFromFloat(qf)
|
||||
}
|
||||
}
|
||||
totalBidQuantity += bidQuantity
|
||||
|
||||
// for maker ask orders
|
||||
if !disableMakerAsk {
|
||||
if s.QuantityScale != nil {
|
||||
qf, err := s.QuantityScale.Scale(i + 1)
|
||||
if err != nil {
|
||||
log.WithError(err).Errorf("quantityScale error")
|
||||
return
|
||||
}
|
||||
|
||||
// override the default bid quantity
|
||||
askQuantity = fixedpoint.NewFromFloat(qf)
|
||||
}
|
||||
}
|
||||
totalAskQuantity += askQuantity
|
||||
}
|
||||
|
||||
bestBidPrice := sourceBook.Bids[0].Price
|
||||
bestAskPrice := sourceBook.Asks[0].Price
|
||||
log.Infof("%s best bid price %f, best ask price: %f", s.Symbol, bestBidPrice.Float64(), bestAskPrice.Float64())
|
||||
|
||||
bidPrice := bestBidPrice.MulFloat64(1.0 - s.BidMargin.Float64())
|
||||
askPrice := bestAskPrice.MulFloat64(1.0 + s.AskMargin.Float64())
|
||||
|
||||
log.Infof("%s quote bid price: %f ask price: %f", s.Symbol, bidPrice.Float64(), askPrice.Float64())
|
||||
|
||||
var submitOrders []types.SubmitOrder
|
||||
var accumulativeBidQuantity, accumulativeAskQuantity fixedpoint.Value
|
||||
var bidQuantity = s.Quantity
|
||||
var askQuantity = s.Quantity
|
||||
for i := 0; i < s.NumLayers; i++ {
|
||||
|
@ -285,6 +263,10 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
|||
bidQuantity = fixedpoint.NewFromFloat(qf)
|
||||
}
|
||||
|
||||
accumulativeBidQuantity += bidQuantity
|
||||
bidPrice := aggregatePrice(sourceBook.Bids, accumulativeBidQuantity)
|
||||
bidPrice = bidPrice.MulFloat64(1.0 - s.BidMargin.Float64())
|
||||
|
||||
if makerQuota.QuoteAsset.Lock(bidQuantity.Mul(bidPrice)) && hedgeQuota.BaseAsset.Lock(bidQuantity) {
|
||||
// if we bought, then we need to sell the base from the hedge session
|
||||
submitOrders = append(submitOrders, types.SubmitOrder{
|
||||
|
@ -304,8 +286,6 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
|||
hedgeQuota.Rollback()
|
||||
}
|
||||
|
||||
bidPrice -= fixedpoint.NewFromFloat(s.makerMarket.TickSize * float64(s.Pips))
|
||||
|
||||
if s.QuantityMultiplier > 0 {
|
||||
bidQuantity = bidQuantity.Mul(s.QuantityMultiplier)
|
||||
}
|
||||
|
@ -323,6 +303,10 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
|||
// override the default bid quantity
|
||||
askQuantity = fixedpoint.NewFromFloat(qf)
|
||||
}
|
||||
accumulativeAskQuantity += askQuantity
|
||||
|
||||
askPrice := aggregatePrice(sourceBook.Asks, accumulativeBidQuantity)
|
||||
askPrice = askPrice.MulFloat64(1.0 + s.AskMargin.Float64())
|
||||
|
||||
if makerQuota.BaseAsset.Lock(askQuantity) && hedgeQuota.QuoteAsset.Lock(askQuantity.Mul(askPrice)) {
|
||||
// if we bought, then we need to sell the base from the hedge session
|
||||
|
@ -341,7 +325,6 @@ func (s *Strategy) updateQuote(ctx context.Context) {
|
|||
makerQuota.Rollback()
|
||||
hedgeQuota.Rollback()
|
||||
}
|
||||
askPrice += fixedpoint.NewFromFloat(s.makerMarket.TickSize * float64(s.Pips))
|
||||
|
||||
if s.QuantityMultiplier > 0 {
|
||||
askQuantity = askQuantity.Mul(s.QuantityMultiplier)
|
||||
|
@ -491,10 +474,11 @@ func (s *Strategy) handleTradeUpdate(trade types.Trade) {
|
|||
since = time.Unix(s.state.AccumulatedSince, 0).In(localTimeZone)
|
||||
}
|
||||
|
||||
s.Notify("%s trade just made profit %f %s, accumulated profit %f %s since %s", s.Symbol,
|
||||
s.Notify("%s trade just made profit %f %s, since %s accumulated net profit %f %s, accumulated loss %f %s", s.Symbol,
|
||||
profit.Float64(), s.state.Position.QuoteCurrency,
|
||||
since.Format(time.RFC822),
|
||||
s.state.AccumulatedPnL.Float64(), s.state.Position.QuoteCurrency,
|
||||
since.Format(time.RFC822))
|
||||
s.state.AccumulatedLoss.Float64(), s.state.Position.QuoteCurrency)
|
||||
|
||||
} else {
|
||||
s.Notify("%s trade modified the position: average cost = %f %s, base = %f", s.Symbol, s.state.Position.AverageCost.Float64(), s.state.Position.QuoteCurrency, s.state.Position.Base.Float64())
|
||||
|
|
36
pkg/strategy/xmaker/strategy_test.go
Normal file
36
pkg/strategy/xmaker/strategy_test.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package xmaker
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/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),
|
||||
},
|
||||
}
|
||||
|
||||
aggregatedPrice1 := aggregatePrice(bids, fixedpoint.NewFromFloat(0.5))
|
||||
assert.Equal(t, fixedpoint.NewFromFloat(1000.0), aggregatedPrice1)
|
||||
|
||||
aggregatedPrice2 := aggregatePrice(bids, fixedpoint.NewFromInt(1))
|
||||
assert.Equal(t, fixedpoint.NewFromFloat(1000.0), aggregatedPrice2)
|
||||
|
||||
aggregatedPrice3 := aggregatePrice(bids, fixedpoint.NewFromInt(2))
|
||||
assert.Equal(t, fixedpoint.NewFromFloat(1100.0), aggregatedPrice3)
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user