mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
techsignal: add funding rate checker
This commit is contained in:
parent
e7fe443cbe
commit
4523135012
|
@ -911,19 +911,35 @@ func (e *Exchange) BatchQueryKLines(ctx context.Context, symbol string, interval
|
|||
return allKLines, nil
|
||||
}
|
||||
|
||||
func (e *Exchange) QueryLastFundingRate(ctx context.Context, symbol string) (fixedpoint.Value, error) {
|
||||
type FundingRate struct {
|
||||
FundingRate fixedpoint.Value
|
||||
FundingTime time.Time
|
||||
Time time.Time
|
||||
}
|
||||
|
||||
func (e *Exchange) QueryLastFundingRate(ctx context.Context, symbol string) (*FundingRate, error) {
|
||||
futuresClient := binance.NewFuturesClient(e.key, e.secret)
|
||||
rates, err := futuresClient.NewFundingRateService().
|
||||
Symbol(symbol).
|
||||
Limit(1).
|
||||
Do(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(rates) == 0 {
|
||||
return 0, errors.New("empty funding rate data")
|
||||
return nil, errors.New("empty funding rate data")
|
||||
}
|
||||
|
||||
return fixedpoint.NewFromString(rates[0].FundingRate)
|
||||
rate := rates[0]
|
||||
fundingRate, err := fixedpoint.NewFromString(rate.FundingRate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &FundingRate{
|
||||
FundingRate: fundingRate,
|
||||
FundingTime: time.Unix(0, rate.FundingTime*int64(time.Millisecond)),
|
||||
Time: time.Unix(0, rate.Time*int64(time.Millisecond)),
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -4,10 +4,12 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/c9s/bbgo/pkg/exchange/binance"
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/leekchan/accounting"
|
||||
"github.com/sirupsen/logrus"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/bbgo"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
|
@ -31,6 +33,12 @@ type Strategy struct {
|
|||
Symbol string `json:"symbol"`
|
||||
Market types.Market `json:"-"`
|
||||
|
||||
FundingRate *struct {
|
||||
High fixedpoint.Value `json:"high"`
|
||||
Neutral fixedpoint.Value `json:"neutral"`
|
||||
DiffThreshold fixedpoint.Value `json:"diffThreshold"`
|
||||
} `json:"fundingRate"`
|
||||
|
||||
SupportDetection []struct {
|
||||
Interval types.Interval `json:"interval"`
|
||||
|
||||
|
@ -74,12 +82,70 @@ func (s *Strategy) Validate() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *Strategy) listenToFundingRate(ctx context.Context, exchange *binance.Exchange) {
|
||||
var previousFundingRate, fundingRate24HoursLow *binance.FundingRate
|
||||
|
||||
fundingRateTicker := time.NewTicker(1 * time.Hour)
|
||||
defer fundingRateTicker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-fundingRateTicker.C:
|
||||
fundingRate, err := exchange.QueryLastFundingRate(ctx, s.Symbol)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("can not query last funding rate")
|
||||
continue
|
||||
}
|
||||
|
||||
if fundingRate.FundingRate >= s.FundingRate.High {
|
||||
s.Notifiability.Notify("%s funding rate is too high! %s > %s",
|
||||
s.Symbol,
|
||||
fundingRate.FundingRate.Percentage(),
|
||||
s.FundingRate.High.Percentage(),
|
||||
)
|
||||
}
|
||||
|
||||
if previousFundingRate != nil {
|
||||
diff := fundingRate.FundingRate - previousFundingRate.FundingRate
|
||||
if diff > fixedpoint.NewFromFloat(0.001*0.01) {
|
||||
s.Notifiability.Notify("%s funding rate changed %s -> %s",
|
||||
s.Symbol,
|
||||
diff.Percentage(),
|
||||
fundingRate.FundingRate.Percentage(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
previousFundingRate = fundingRate
|
||||
if fundingRate24HoursLow != nil {
|
||||
if fundingRate24HoursLow.Time.Before(time.Now().Add(24 * time.Hour)) {
|
||||
fundingRate24HoursLow = fundingRate
|
||||
}
|
||||
if fundingRate.FundingRate < fundingRate24HoursLow.FundingRate {
|
||||
fundingRate24HoursLow = fundingRate
|
||||
}
|
||||
} else {
|
||||
fundingRate24HoursLow = fundingRate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession) error {
|
||||
standardIndicatorSet, ok := session.StandardIndicatorSet(s.Symbol)
|
||||
if !ok {
|
||||
return fmt.Errorf("standardIndicatorSet is nil, symbol %s", s.Symbol)
|
||||
}
|
||||
|
||||
if s.FundingRate != nil {
|
||||
if binanceExchange, ok := session.Exchange.(*binance.Exchange); ok {
|
||||
go s.listenToFundingRate(ctx, binanceExchange)
|
||||
} else {
|
||||
log.Error("exchange does not support funding rate api")
|
||||
}
|
||||
}
|
||||
|
||||
session.MarketDataStream.OnKLineClosed(func(kline types.KLine) {
|
||||
// skip k-lines from other symbols
|
||||
if kline.Symbol != s.Symbol {
|
||||
|
|
Loading…
Reference in New Issue
Block a user