Skip to content

Commit

Permalink
xfunding: record pending transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
c9s committed Mar 23, 2023
1 parent 1660861 commit b7edc38
Showing 1 changed file with 35 additions and 21 deletions.
56 changes: 35 additions & 21 deletions pkg/strategy/xfunding/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,27 +85,30 @@ type Strategy struct {
MinQuoteVolume fixedpoint.Value `json:"minQuoteVolume"`
} `json:"supportDetection"`

ProfitStats *types.ProfitStats `persistence:"profit_stats"`
SpotSession string `json:"spotSession"`
FuturesSession string `json:"futuresSession"`

SpotPosition *types.Position `persistence:"spot_position"`
FuturesPosition *types.Position `persistence:"futures_position"`
ProfitStats *types.ProfitStats `persistence:"profit_stats"`
SpotPosition *types.Position `persistence:"spot_position"`
FuturesPosition *types.Position `persistence:"futures_position"`

spotSession, futuresSession *bbgo.ExchangeSession
State *State `persistence:"state"`

spotSession, futuresSession *bbgo.ExchangeSession
spotOrderExecutor, futuresOrderExecutor *bbgo.GeneralOrderExecutor
spotMarket, futuresMarket types.Market

SpotSession string `json:"spotSession"`
FuturesSession string `json:"futuresSession"`

// positionAction is default to NoOp
positionAction PositionAction

// positionType is the futures position type
// currently we only support short position for the positive funding rate
positionType types.PositionType
}

usedQuoteInvestment fixedpoint.Value
type State struct {
PendingBaseTransfer fixedpoint.Value `json:"pendingBaseTransfer"`
UsedQuoteInvestment fixedpoint.Value `json:"usedQuoteInvestment"`
}

func (s *Strategy) ID() string {
Expand Down Expand Up @@ -198,8 +201,6 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
func (s *Strategy) CrossRun(ctx context.Context, orderExecutionRouter bbgo.OrderExecutionRouter, sessions map[string]*bbgo.ExchangeSession) error {
instanceID := s.InstanceID()

s.usedQuoteInvestment = fixedpoint.Zero

s.spotSession = sessions[s.SpotSession]
s.futuresSession = sessions[s.FuturesSession]

Expand Down Expand Up @@ -234,6 +235,13 @@ func (s *Strategy) CrossRun(ctx context.Context, orderExecutionRouter bbgo.Order
s.SpotPosition = types.NewPositionFromMarket(s.spotMarket)
}

if s.State == nil {
s.State = &State{
PendingBaseTransfer: fixedpoint.Zero,
UsedQuoteInvestment: fixedpoint.Zero,
}
}

binanceFutures := s.futuresSession.Exchange.(*binance.Exchange)
binanceSpot := s.spotSession.Exchange.(*binance.Exchange)
_ = binanceSpot
Expand All @@ -255,8 +263,8 @@ func (s *Strategy) CrossRun(ctx context.Context, orderExecutionRouter bbgo.Order
}

// TODO: add mutex lock for this modification
s.usedQuoteInvestment = s.usedQuoteInvestment.Add(trade.QuoteQuantity)
if s.usedQuoteInvestment.Compare(s.QuoteInvestment) >= 0 {
s.State.UsedQuoteInvestment = s.State.UsedQuoteInvestment.Add(trade.QuoteQuantity)
if s.State.UsedQuoteInvestment.Compare(s.QuoteInvestment) >= 0 {
s.positionAction = PositionNoOp
}

Expand All @@ -265,7 +273,7 @@ func (s *Strategy) CrossRun(ctx context.Context, orderExecutionRouter bbgo.Order
if err := backoff.RetryGeneric(ctx, func() error {
return s.transferIn(ctx, binanceSpot, trade)
}); err != nil {
log.WithError(err).Errorf("transfer in retry failed")
log.WithError(err).Errorf("spot-to-futures transfer in retry failed")
return
}

Expand Down Expand Up @@ -348,14 +356,20 @@ func (s *Strategy) transferIn(ctx context.Context, ex *binance.Exchange, trade t
}

// TODO: according to the fee, we might not be able to get enough balance greater than the trade quantity, we can adjust the quantity here
if b.Available.Compare(trade.Quantity) >= 0 {
log.Infof("transfering futures account asset %s %s", trade.Quantity, currency)
if err := ex.TransferFuturesAccountAsset(ctx, currency, trade.Quantity, types.TransferIn); err != nil {
log.WithError(err).Errorf("spot-to-futures transfer error")
return err
}
if b.Available.Compare(trade.Quantity) < 0 {
log.Infof("adding to pending base transfer: %s %s", trade.Quantity, currency)
s.State.PendingBaseTransfer = s.State.PendingBaseTransfer.Add(trade.Quantity)
return nil
}

amount := s.State.PendingBaseTransfer.Add(trade.Quantity)

log.Infof("transfering futures account asset %s %s", amount, currency)
if err := ex.TransferFuturesAccountAsset(ctx, currency, amount, types.TransferIn); err != nil {
return err
}

s.State.PendingBaseTransfer = fixedpoint.Zero
return nil
}

Expand Down Expand Up @@ -470,11 +484,11 @@ func (s *Strategy) increaseSpotPosition(ctx context.Context) {
// TODO: compare with the futures position and reduce the position

case PositionOpening:
if s.usedQuoteInvestment.Compare(s.QuoteInvestment) >= 0 {
if s.State.UsedQuoteInvestment.Compare(s.QuoteInvestment) >= 0 {
return
}

leftQuote := s.QuoteInvestment.Sub(s.usedQuoteInvestment)
leftQuote := s.QuoteInvestment.Sub(s.State.UsedQuoteInvestment)
orderPrice := ticker.Buy
orderQuantity := fixedpoint.Min(s.IncrementalQuoteQuantity, leftQuote).Div(orderPrice)
orderQuantity = fixedpoint.Max(orderQuantity, s.spotMarket.MinQuantity)
Expand Down

0 comments on commit b7edc38

Please sign in to comment.