mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
xfunding: add mutex
This commit is contained in:
parent
02c28a07cc
commit
1b5126c9a1
|
@ -9,6 +9,12 @@ notifications:
|
|||
orderUpdate: true
|
||||
submitOrder: true
|
||||
|
||||
persistence:
|
||||
redis:
|
||||
host: 127.0.0.1
|
||||
port: 6379
|
||||
db: 1
|
||||
|
||||
sessions:
|
||||
binance:
|
||||
exchange: binance
|
||||
|
|
|
@ -33,7 +33,7 @@ func AdjustQuantityByMinAmount(quantity, currentPrice, minAmount fixedpoint.Valu
|
|||
amount := currentPrice.Mul(quantity)
|
||||
if amount.Compare(minAmount) < 0 {
|
||||
ratio := minAmount.Div(amount)
|
||||
quantity = quantity.Mul(ratio)
|
||||
return quantity.Mul(ratio)
|
||||
}
|
||||
|
||||
return quantity
|
||||
|
|
|
@ -94,7 +94,9 @@ type Strategy struct {
|
|||
FuturesPosition *types.Position `persistence:"futures_position"`
|
||||
|
||||
State *State `persistence:"state"`
|
||||
mu sync.Mutex
|
||||
|
||||
// mu is used for locking state
|
||||
mu sync.Mutex
|
||||
|
||||
spotSession, futuresSession *bbgo.ExchangeSession
|
||||
spotOrderExecutor, futuresOrderExecutor *bbgo.GeneralOrderExecutor
|
||||
|
@ -246,6 +248,9 @@ func (s *Strategy) CrossRun(ctx context.Context, orderExecutionRouter bbgo.Order
|
|||
}
|
||||
}
|
||||
|
||||
log.Infof("loaded spot position: %s", s.SpotPosition.String())
|
||||
log.Infof("loaded futures position: %s", s.FuturesPosition.String())
|
||||
|
||||
binanceFutures := s.futuresSession.Exchange.(*binance.Exchange)
|
||||
binanceSpot := s.spotSession.Exchange.(*binance.Exchange)
|
||||
_ = binanceSpot
|
||||
|
@ -428,7 +433,7 @@ func (s *Strategy) syncFuturesPosition(ctx context.Context) {
|
|||
spotBase := s.SpotPosition.GetBase() // should be positive base quantity here
|
||||
futuresBase := s.FuturesPosition.GetBase() // should be negative base quantity here
|
||||
|
||||
if spotBase.IsZero() {
|
||||
if spotBase.IsZero() || spotBase.Sign() < 0 {
|
||||
// skip when spot base is zero
|
||||
return
|
||||
}
|
||||
|
@ -449,14 +454,25 @@ func (s *Strategy) syncFuturesPosition(ctx context.Context) {
|
|||
}
|
||||
log.Infof("calculated futures account quote value = %s", quoteValue.String())
|
||||
|
||||
if spotBase.Sign() > 0 && futuresBase.Neg().Compare(spotBase) < 0 {
|
||||
// max futures base position (without negative sign)
|
||||
maxFuturesBasePosition := fixedpoint.Min(
|
||||
spotBase.Mul(s.Leverage),
|
||||
s.State.TotalBaseTransfer.Mul(s.Leverage))
|
||||
|
||||
// if - futures position < max futures position, increase it
|
||||
if futuresBase.Neg().Compare(maxFuturesBasePosition) < 0 {
|
||||
orderPrice := ticker.Sell
|
||||
diffQuantity := spotBase.Sub(futuresBase.Neg().Mul(s.Leverage))
|
||||
diffQuantity := maxFuturesBasePosition.Sub(futuresBase.Neg())
|
||||
|
||||
if diffQuantity.Sign() < 0 {
|
||||
log.Errorf("unexpected negative position diff: %s", diffQuantity.String())
|
||||
return
|
||||
}
|
||||
|
||||
log.Infof("position diff quantity: %s", diffQuantity.String())
|
||||
|
||||
orderQuantity := fixedpoint.Max(diffQuantity, s.futuresMarket.MinQuantity)
|
||||
orderQuantity = bbgo.AdjustQuantityByMinAmount(orderQuantity, orderPrice, s.futuresMarket.MinNotional)
|
||||
orderQuantity = s.futuresMarket.AdjustQuantityByMinNotional(orderQuantity, orderPrice)
|
||||
if s.futuresMarket.IsDustQuantity(orderQuantity, orderPrice) {
|
||||
log.Infof("skip futures order with dust quantity %s, market = %+v", orderQuantity.String(), s.futuresMarket)
|
||||
return
|
||||
|
@ -486,12 +502,6 @@ func (s *Strategy) syncSpotPosition(ctx context.Context) {
|
|||
}
|
||||
|
||||
func (s *Strategy) increaseSpotPosition(ctx context.Context) {
|
||||
ticker, err := s.spotSession.Exchange.QueryTicker(ctx, s.Symbol)
|
||||
if err != nil {
|
||||
log.WithError(err).Errorf("can not query ticker")
|
||||
return
|
||||
}
|
||||
|
||||
if s.positionType != types.PositionShort {
|
||||
log.Errorf("funding long position type is not supported")
|
||||
return
|
||||
|
@ -507,13 +517,27 @@ func (s *Strategy) increaseSpotPosition(ctx context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
_ = s.spotOrderExecutor.GracefulCancel(ctx)
|
||||
|
||||
ticker, err := s.spotSession.Exchange.QueryTicker(ctx, s.Symbol)
|
||||
if err != nil {
|
||||
log.WithError(err).Errorf("can not query ticker")
|
||||
return
|
||||
}
|
||||
|
||||
leftQuota := s.QuoteInvestment.Sub(s.State.UsedQuoteInvestment)
|
||||
|
||||
orderPrice := ticker.Buy
|
||||
orderQuantity := fixedpoint.Min(s.IncrementalQuoteQuantity, leftQuota).Div(orderPrice)
|
||||
orderQuantity = fixedpoint.Max(orderQuantity, s.spotMarket.MinQuantity)
|
||||
|
||||
_ = s.spotOrderExecutor.GracefulCancel(ctx)
|
||||
log.Infof("initial spot order quantity %s", orderQuantity.String())
|
||||
|
||||
orderQuantity = fixedpoint.Max(orderQuantity, s.spotMarket.MinQuantity)
|
||||
orderQuantity = s.spotMarket.AdjustQuantityByMinNotional(orderQuantity, orderPrice)
|
||||
|
||||
if s.spotMarket.IsDustQuantity(orderQuantity, orderPrice) {
|
||||
return
|
||||
}
|
||||
|
||||
submitOrder := types.SubmitOrder{
|
||||
Symbol: s.Symbol,
|
||||
|
@ -542,6 +566,10 @@ func (s *Strategy) detectPremiumIndex(premiumIndex *types.PremiumIndex) (changed
|
|||
|
||||
if s.ShortFundingRate != nil {
|
||||
if fundingRate.Compare(s.ShortFundingRate.High) >= 0 {
|
||||
|
||||
log.Infof("funding rate %s is higher than the High threshold %s, start opening position...",
|
||||
fundingRate.Percentage(), s.ShortFundingRate.High.Percentage())
|
||||
|
||||
s.positionAction = PositionOpening
|
||||
s.positionType = types.PositionShort
|
||||
changed = true
|
||||
|
|
Loading…
Reference in New Issue
Block a user