mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-08 07:26:48 +00:00
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:
@@ -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) {
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user