mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-26 00:35:15 +00:00
xfunding: add syncFundingFeeRecords method
This commit is contained in:
parent
a3f96871e2
commit
4d1f691300
|
@ -59,4 +59,4 @@ crossExchangeStrategies:
|
||||||
low: -0.01%
|
low: -0.01%
|
||||||
|
|
||||||
## reset will reset the spot/futures positions, the transfer stats and the position state.
|
## reset will reset the spot/futures positions, the transfer stats and the position state.
|
||||||
reset: true
|
# reset: true
|
||||||
|
|
|
@ -9,7 +9,9 @@ import (
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/c9s/bbgo/pkg/exchange/batch"
|
||||||
"github.com/c9s/bbgo/pkg/exchange/binance"
|
"github.com/c9s/bbgo/pkg/exchange/binance"
|
||||||
|
"github.com/c9s/bbgo/pkg/exchange/binance/binanceapi"
|
||||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||||
"github.com/c9s/bbgo/pkg/util/backoff"
|
"github.com/c9s/bbgo/pkg/util/backoff"
|
||||||
|
|
||||||
|
@ -157,6 +159,8 @@ type Strategy struct {
|
||||||
spotOrderExecutor, futuresOrderExecutor *bbgo.GeneralOrderExecutor
|
spotOrderExecutor, futuresOrderExecutor *bbgo.GeneralOrderExecutor
|
||||||
spotMarket, futuresMarket types.Market
|
spotMarket, futuresMarket types.Market
|
||||||
|
|
||||||
|
binanceFutures, binanceSpot *binance.Exchange
|
||||||
|
|
||||||
// positionType is the futures position type
|
// positionType is the futures position type
|
||||||
// currently we only support short position for the positive funding rate
|
// currently we only support short position for the positive funding rate
|
||||||
positionType types.PositionType
|
positionType types.PositionType
|
||||||
|
@ -255,11 +259,13 @@ func (s *Strategy) CrossRun(ctx context.Context, orderExecutionRouter bbgo.Order
|
||||||
s.spotMarket, _ = s.spotSession.Market(s.Symbol)
|
s.spotMarket, _ = s.spotSession.Market(s.Symbol)
|
||||||
s.futuresMarket, _ = s.futuresSession.Market(s.Symbol)
|
s.futuresMarket, _ = s.futuresSession.Market(s.Symbol)
|
||||||
|
|
||||||
binanceFutures, ok := s.futuresSession.Exchange.(*binance.Exchange)
|
var ok bool
|
||||||
|
s.binanceFutures, ok = s.futuresSession.Exchange.(*binance.Exchange)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errNotBinanceExchange
|
return errNotBinanceExchange
|
||||||
}
|
}
|
||||||
binanceSpot, ok := s.spotSession.Exchange.(*binance.Exchange)
|
|
||||||
|
s.binanceSpot, ok = s.spotSession.Exchange.(*binance.Exchange)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errNotBinanceExchange
|
return errNotBinanceExchange
|
||||||
}
|
}
|
||||||
|
@ -283,9 +289,10 @@ func (s *Strategy) CrossRun(ctx context.Context, orderExecutionRouter bbgo.Order
|
||||||
if s.ProfitStats == nil || s.Reset {
|
if s.ProfitStats == nil || s.Reset {
|
||||||
s.ProfitStats = &ProfitStats{
|
s.ProfitStats = &ProfitStats{
|
||||||
ProfitStats: types.NewProfitStats(s.Market),
|
ProfitStats: types.NewProfitStats(s.Market),
|
||||||
|
|
||||||
// when receiving funding fee, the funding fee asset is the quote currency of that market.
|
// when receiving funding fee, the funding fee asset is the quote currency of that market.
|
||||||
FundingFeeCurrency: s.futuresMarket.QuoteCurrency,
|
FundingFeeCurrency: s.futuresMarket.QuoteCurrency,
|
||||||
|
TotalFundingFee: fixedpoint.Zero,
|
||||||
|
FundingFeeRecords: nil,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,6 +314,12 @@ func (s *Strategy) CrossRun(ctx context.Context, orderExecutionRouter bbgo.Order
|
||||||
|
|
||||||
log.Infof("loaded spot position: %s", s.SpotPosition.String())
|
log.Infof("loaded spot position: %s", s.SpotPosition.String())
|
||||||
log.Infof("loaded futures position: %s", s.FuturesPosition.String())
|
log.Infof("loaded futures position: %s", s.FuturesPosition.String())
|
||||||
|
log.Infof("loaded neutral position: %s", s.NeutralPosition.String())
|
||||||
|
|
||||||
|
// sync funding fee txns
|
||||||
|
if !s.ProfitStats.LastFundingFeeTime.IsZero() {
|
||||||
|
s.syncFundingFeeRecords(ctx, s.ProfitStats.LastFundingFeeTime)
|
||||||
|
}
|
||||||
|
|
||||||
s.spotOrderExecutor = s.allocateOrderExecutor(ctx, s.spotSession, instanceID, s.SpotPosition)
|
s.spotOrderExecutor = s.allocateOrderExecutor(ctx, s.spotSession, instanceID, s.SpotPosition)
|
||||||
s.spotOrderExecutor.TradeCollector().OnTrade(func(trade types.Trade, profit fixedpoint.Value, netProfit fixedpoint.Value) {
|
s.spotOrderExecutor.TradeCollector().OnTrade(func(trade types.Trade, profit fixedpoint.Value, netProfit fixedpoint.Value) {
|
||||||
|
@ -334,7 +347,7 @@ func (s *Strategy) CrossRun(ctx context.Context, orderExecutionRouter bbgo.Order
|
||||||
// if we have trade, try to query the balance and transfer the balance to the futures wallet account
|
// if we have trade, try to query the balance and transfer the balance to the futures wallet account
|
||||||
// TODO: handle missing trades here. If the process crashed during the transfer, how to recover?
|
// TODO: handle missing trades here. If the process crashed during the transfer, how to recover?
|
||||||
if err := backoff.RetryGeneral(ctx, func() error {
|
if err := backoff.RetryGeneral(ctx, func() error {
|
||||||
return s.transferIn(ctx, binanceSpot, s.spotMarket.BaseCurrency, trade)
|
return s.transferIn(ctx, s.binanceSpot, s.spotMarket.BaseCurrency, trade)
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.WithError(err).Errorf("spot-to-futures transfer in retry failed")
|
log.WithError(err).Errorf("spot-to-futures transfer in retry failed")
|
||||||
return
|
return
|
||||||
|
@ -358,7 +371,7 @@ func (s *Strategy) CrossRun(ctx context.Context, orderExecutionRouter bbgo.Order
|
||||||
switch s.getPositionState() {
|
switch s.getPositionState() {
|
||||||
case PositionClosing:
|
case PositionClosing:
|
||||||
if err := backoff.RetryGeneral(ctx, func() error {
|
if err := backoff.RetryGeneral(ctx, func() error {
|
||||||
return s.transferOut(ctx, binanceSpot, s.spotMarket.BaseCurrency, trade)
|
return s.transferOut(ctx, s.binanceSpot, s.spotMarket.BaseCurrency, trade)
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.WithError(err).Errorf("spot-to-futures transfer in retry failed")
|
log.WithError(err).Errorf("spot-to-futures transfer in retry failed")
|
||||||
return
|
return
|
||||||
|
@ -368,7 +381,7 @@ func (s *Strategy) CrossRun(ctx context.Context, orderExecutionRouter bbgo.Order
|
||||||
})
|
})
|
||||||
|
|
||||||
s.futuresSession.MarketDataStream.OnKLineClosed(types.KLineWith(s.Symbol, s.Interval, func(kline types.KLine) {
|
s.futuresSession.MarketDataStream.OnKLineClosed(types.KLineWith(s.Symbol, s.Interval, func(kline types.KLine) {
|
||||||
s.queryAndDetectPremiumIndex(ctx, binanceFutures)
|
s.queryAndDetectPremiumIndex(ctx, s.binanceFutures)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
if binanceStream, ok := s.futuresSession.UserDataStream.(*binance.Stream); ok {
|
if binanceStream, ok := s.futuresSession.UserDataStream.(*binance.Stream); ok {
|
||||||
|
@ -448,6 +461,29 @@ func (s *Strategy) CrossRun(ctx context.Context, orderExecutionRouter bbgo.Order
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Strategy) syncFundingFeeRecords(ctx context.Context, since time.Time) {
|
||||||
|
now := time.Now()
|
||||||
|
q := batch.BinanceFuturesIncomeBatchQuery{
|
||||||
|
BinanceFuturesIncomeHistoryService: s.binanceFutures,
|
||||||
|
}
|
||||||
|
|
||||||
|
dataC, errC := q.Query(ctx, s.Symbol, binanceapi.FuturesIncomeFundingFee, since, now)
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
|
||||||
|
case income := <-dataC:
|
||||||
|
log.Infof("income: %+v", income)
|
||||||
|
|
||||||
|
case err := <-errC:
|
||||||
|
log.WithError(err).Errorf("unable to query futures income history")
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Strategy) queryAndDetectPremiumIndex(ctx context.Context, binanceFutures *binance.Exchange) {
|
func (s *Strategy) queryAndDetectPremiumIndex(ctx context.Context, binanceFutures *binance.Exchange) {
|
||||||
premiumIndex, err := binanceFutures.QueryPremiumIndex(ctx, s.Symbol)
|
premiumIndex, err := binanceFutures.QueryPremiumIndex(ctx, s.Symbol)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user