Binance,OKx: Implement fetching funding rates (#1239)

* adds basic groundwork for rates on binance

* more into rates on binance

* rm redudant redundancy, add payments

* mini commit before merging with testnet ability branch

* changes function signature and fixes resulting build

* gets billing data too

* funding rates package, features use, testnet reimpl

* new endpoint, refinements and tests

* cli fix, rpc impl, testing, payments

* fixups from looking at code

* typo fix

* niteroos

* merge fixes

* adds test, fixes cli issues

* woah nelly
This commit is contained in:
Scott
2023-07-26 14:25:43 +10:00
committed by GitHub
parent 2ad9304045
commit 471f4f21c4
39 changed files with 5785 additions and 3416 deletions

View File

@@ -12,6 +12,7 @@ import (
"github.com/thrasher-corp/gocryptotrader/common"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/fundingrate"
)
// SetupPositionController creates a position controller
@@ -126,7 +127,7 @@ func (c *PositionController) GetPositionsForExchange(exch string, item asset.Ite
}
// TrackFundingDetails applies funding rate details to a tracked position
func (c *PositionController) TrackFundingDetails(d *FundingRates) error {
func (c *PositionController) TrackFundingDetails(d *fundingrate.Rates) error {
if c == nil {
return fmt.Errorf("position controller %w", common.ErrNilPointer)
}
@@ -432,7 +433,7 @@ func (m *MultiPositionTracker) TrackNewOrder(d *Detail) error {
}
// TrackFundingDetails applies funding rate details to a tracked position
func (m *MultiPositionTracker) TrackFundingDetails(d *FundingRates) error {
func (m *MultiPositionTracker) TrackFundingDetails(d *fundingrate.Rates) error {
if m == nil {
return fmt.Errorf("multi-position tracker %w", common.ErrNilPointer)
}
@@ -550,9 +551,9 @@ func (p *PositionTracker) GetStats() *Position {
}
if p.fundingRateDetails != nil {
frs := make([]FundingRate, len(p.fundingRateDetails.FundingRates))
frs := make([]fundingrate.Rate, len(p.fundingRateDetails.FundingRates))
copy(frs, p.fundingRateDetails.FundingRates)
pos.FundingRates = FundingRates{
pos.FundingRates = fundingrate.Rates{
Exchange: p.fundingRateDetails.Exchange,
Asset: p.fundingRateDetails.Asset,
Pair: p.fundingRateDetails.Pair,
@@ -660,7 +661,7 @@ func (p *PositionTracker) GetLatestPNLSnapshot() (PNLResult, error) {
}
// TrackFundingDetails sets funding rates to a position
func (p *PositionTracker) TrackFundingDetails(d *FundingRates) error {
func (p *PositionTracker) TrackFundingDetails(d *fundingrate.Rates) error {
if p == nil {
return fmt.Errorf("position tracker %w", common.ErrNilPointer)
}
@@ -688,7 +689,7 @@ func (p *PositionTracker) TrackFundingDetails(d *FundingRates) error {
return fmt.Errorf("%w for timeframe %v %v %v %v-%v", ErrNoPositionsFound, p.exchange, p.asset, p.contractPair, d.StartDate, d.EndDate)
}
if p.fundingRateDetails == nil {
p.fundingRateDetails = &FundingRates{
p.fundingRateDetails = &fundingrate.Rates{
Exchange: d.Exchange,
Asset: d.Asset,
Pair: d.Pair,
@@ -699,7 +700,7 @@ func (p *PositionTracker) TrackFundingDetails(d *FundingRates) error {
PaymentSum: d.PaymentSum,
}
}
rates := make([]FundingRate, 0, len(d.FundingRates))
rates := make([]fundingrate.Rate, 0, len(d.FundingRates))
fundingRates:
for i := range d.FundingRates {
if d.FundingRates[i].Time.Before(p.openingDate) ||
@@ -823,12 +824,12 @@ func (p *PositionTracker) TrackNewOrder(d *Detail, isInitialOrder bool) error {
p.longPositions = append(p.longPositions, d.Copy())
}
}
var shortSide, longSide decimal.Decimal
var shortSideAmount, longSideAmount decimal.Decimal
for i := range p.shortPositions {
shortSide = shortSide.Add(decimal.NewFromFloat(p.shortPositions[i].Amount))
shortSideAmount = shortSideAmount.Add(decimal.NewFromFloat(p.shortPositions[i].Amount))
}
for i := range p.longPositions {
longSide = longSide.Add(decimal.NewFromFloat(p.longPositions[i].Amount))
longSideAmount = longSideAmount.Add(decimal.NewFromFloat(p.longPositions[i].Amount))
}
if isInitialOrder {
@@ -927,18 +928,18 @@ func (p *PositionTracker) TrackNewOrder(d *Detail, isInitialOrder bool) error {
p.unrealisedPNL = result.UnrealisedPNL
switch {
case longSide.GreaterThan(shortSide):
case longSideAmount.GreaterThan(shortSideAmount):
p.latestDirection = Long
case shortSide.GreaterThan(longSide):
case shortSideAmount.GreaterThan(longSideAmount):
p.latestDirection = Short
default:
p.latestDirection = ClosePosition
}
if p.latestDirection.IsLong() {
p.exposure = longSide.Sub(shortSide)
p.exposure = longSideAmount.Sub(shortSideAmount)
} else {
p.exposure = shortSide.Sub(longSide)
p.exposure = shortSideAmount.Sub(longSideAmount)
}
if p.exposure.Equal(decimal.Zero) {

View File

@@ -10,6 +10,7 @@ import (
"github.com/thrasher-corp/gocryptotrader/common"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/fundingrate"
)
const testExchange = "test"
@@ -538,8 +539,8 @@ func TestGetStats(t *testing.T) {
}
p.exchange = testExchange
p.fundingRateDetails = &FundingRates{
FundingRates: []FundingRate{
p.fundingRateDetails = &fundingrate.Rates{
FundingRates: []fundingrate.Rate{
{},
},
}
@@ -1264,7 +1265,7 @@ func TestPCTrackFundingDetails(t *testing.T) {
}
p := currency.NewPair(currency.BTC, currency.PERP)
rates := &FundingRates{
rates := &fundingrate.Rates{
Asset: asset.Futures,
Pair: p,
}
@@ -1296,7 +1297,7 @@ func TestPCTrackFundingDetails(t *testing.T) {
rates.StartDate = tn.Add(-time.Hour)
rates.EndDate = tn
rates.FundingRates = []FundingRate{
rates.FundingRates = []fundingrate.Rate{
{
Time: tn,
Rate: decimal.NewFromInt(1337),
@@ -1323,7 +1324,7 @@ func TestMPTTrackFundingDetails(t *testing.T) {
}
cp := currency.NewPair(currency.BTC, currency.PERP)
rates := &FundingRates{
rates := &fundingrate.Rates{
Asset: asset.Futures,
Pair: cp,
}
@@ -1333,7 +1334,7 @@ func TestMPTTrackFundingDetails(t *testing.T) {
}
mpt.exchange = testExchange
rates = &FundingRates{
rates = &fundingrate.Rates{
Exchange: testExchange,
Asset: asset.Futures,
Pair: cp,
@@ -1367,7 +1368,7 @@ func TestMPTTrackFundingDetails(t *testing.T) {
rates.StartDate = tn.Add(-time.Hour)
rates.EndDate = tn
rates.FundingRates = []FundingRate{
rates.FundingRates = []fundingrate.Rate{
{
Time: tn,
Rate: decimal.NewFromInt(1337),
@@ -1392,7 +1393,7 @@ func TestPTTrackFundingDetails(t *testing.T) {
}
cp := currency.NewPair(currency.BTC, currency.PERP)
rates := &FundingRates{
rates := &fundingrate.Rates{
Exchange: testExchange,
Asset: asset.Futures,
Pair: cp,
@@ -1431,7 +1432,7 @@ func TestPTTrackFundingDetails(t *testing.T) {
t.Errorf("received '%v' expected '%v", err, nil)
}
rates.FundingRates = []FundingRate{
rates.FundingRates = []fundingrate.Rate{
{
Time: rates.StartDate,
Rate: decimal.NewFromInt(1337),

View File

@@ -9,6 +9,7 @@ import (
"github.com/shopspring/decimal"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/fundingrate"
)
var (
@@ -194,7 +195,7 @@ type PositionTracker struct {
shortPositions []Detail
longPositions []Detail
pnlHistory []PNLResult
fundingRateDetails *FundingRates
fundingRateDetails *fundingrate.Rates
}
// PositionTrackerSetup contains all required fields to
@@ -302,7 +303,7 @@ type Position struct {
CloseDate time.Time
Orders []Detail
PNLHistory []PNLResult
FundingRates FundingRates
FundingRates fundingrate.Rates
}
// PositionSummaryRequest is used to request a summary of an open position
@@ -343,36 +344,6 @@ type PositionSummary struct {
TotalCollateral decimal.Decimal
}
// FundingRatesRequest is used to request funding rate details for a position
type FundingRatesRequest struct {
Asset asset.Item
Pairs currency.Pairs
StartDate time.Time
EndDate time.Time
IncludePayments bool
IncludePredictedRate bool
}
// FundingRates is used to return funding rate details for a position
type FundingRates struct {
Exchange string
Asset asset.Item
Pair currency.Pair
StartDate time.Time
EndDate time.Time
LatestRate FundingRate
PredictedUpcomingRate FundingRate
FundingRates []FundingRate
PaymentSum decimal.Decimal
}
// FundingRate holds details for an individual funding rate
type FundingRate struct {
Time time.Time
Rate decimal.Decimal
Payment decimal.Decimal
}
// PositionDetails are used to track open positions
// in the order manager
type PositionDetails struct {