diff --git a/v2/futures/client.go b/v2/futures/client.go index e8832dc9..ae0b5878 100644 --- a/v2/futures/client.go +++ b/v2/futures/client.go @@ -546,6 +546,16 @@ func (c *Client) NewFundingRateService() *FundingRateService { return &FundingRateService{c: c} } +// NewFundingRateHistoryService init funding rate history service +func (c *Client) NewFundingRateHistoryService() *FundingRateHistoryService { + return &FundingRateHistoryService{c: c} +} + +// NewFundingRateInfoService init funding rate info service +func (c *Client) NewFundingRateInfoService() *FundingRateInfoService { + return &FundingRateInfoService{c: c} +} + // NewListUserLiquidationOrdersService init list user's liquidation orders service func (c *Client) NewListUserLiquidationOrdersService() *ListUserLiquidationOrdersService { return &ListUserLiquidationOrdersService{c: c} diff --git a/v2/futures/funding_rate_history.go b/v2/futures/funding_rate_history.go new file mode 100644 index 00000000..ab0b5f24 --- /dev/null +++ b/v2/futures/funding_rate_history.go @@ -0,0 +1,82 @@ +package futures + +import ( + "context" + "encoding/json" + "net/http" + + "github.com/adshao/go-binance/v2/common" +) + +// FundingRateHistoryService gets funding rate history +type FundingRateHistoryService struct { + c *Client + symbol *string + startTime *int64 + endTime *int64 + limit *int +} + +// Symbol set symbol +func (s *FundingRateHistoryService) Symbol(symbol string) *FundingRateHistoryService { + s.symbol = &symbol + return s +} + +// StartTime set startTime +func (s *FundingRateHistoryService) StartTime(startTime int64) *FundingRateHistoryService { + s.startTime = &startTime + return s +} + +// EndTime set startTime +func (s *FundingRateHistoryService) EndTime(endTime int64) *FundingRateHistoryService { + s.endTime = &endTime + return s +} + +// Limit set limit +func (s *FundingRateHistoryService) Limit(limit int) *FundingRateHistoryService { + s.limit = &limit + return s +} + +// Do send request +func (s *FundingRateHistoryService) Do(ctx context.Context, opts ...RequestOption) (res []*FundingRateHistory, err error) { + r := &request{ + method: http.MethodGet, + endpoint: "/fapi/v1/fundingRate", + secType: secTypeNone, + } + if s.symbol != nil { + r.setParam("symbol", *s.symbol) + } + if s.startTime != nil { + r.setParam("startTime", *s.startTime) + } + if s.endTime != nil { + r.setParam("endTime", *s.endTime) + } + if s.limit != nil { + r.setParam("limit", *s.limit) + } + data, _, err := s.c.callAPI(ctx, r, opts...) + data = common.ToJSONList(data) + if err != nil { + return []*FundingRateHistory{}, err + } + res = make([]*FundingRateHistory, 0) + err = json.Unmarshal(data, &res) + if err != nil { + return []*FundingRateHistory{}, err + } + return res, nil +} + +// FundingRateHistory defines funding rate history data +type FundingRateHistory struct { + Symbol string `json:"symbol"` + FundingTime int64 `json:"fundingTime"` + FundingRate string `json:"fundingRate"` + MarkPrice string `json:"markPrice"` +} diff --git a/v2/futures/funding_rate_history_test.go b/v2/futures/funding_rate_history_test.go new file mode 100644 index 00000000..39ee476d --- /dev/null +++ b/v2/futures/funding_rate_history_test.go @@ -0,0 +1,59 @@ +package futures + +import ( + "github.com/stretchr/testify/suite" + "testing" +) + +type fundingRateHistoryServiceTestSuite struct { + baseTestSuite +} + +func TestFundingRateHistoryService(t *testing.T) { + suite.Run(t, new(fundingRateHistoryServiceTestSuite)) +} + +func (s *fundingRateHistoryServiceTestSuite) TestGetFundingRateHistory() { + data := []byte(`[{ + "symbol": "BTCUSDT", + "fundingTime": 1698768000000, + "fundingRate": "0.00010000", + "markPrice": "34287.54619963" + }]`) + s.mockDo(data, nil) + defer s.assertDo() + + symbol := "BTCUSDT" + startTime := int64(1576566020000) + endTime := int64(1676566020000) + limit := 10 + s.assertReq(func(r *request) { + e := newRequest().setParams(params{ + "symbol": symbol, + "startTime": startTime, + "endTime": endTime, + "limit": limit, + }) + s.assertRequestEqual(e, r) + }) + + res, err := s.client.NewFundingRateHistoryService().Symbol(symbol).StartTime(startTime).EndTime(endTime).Limit(limit).Do(newContext()) + s.r().NoError(err) + e := []*FundingRateHistory{ + { + Symbol: symbol, + FundingTime: 1698768000000, + FundingRate: "0.00010000", + MarkPrice: "34287.54619963", + }, + } + s.assertFundingRateHistoryEqual(e, res) +} + +func (s *fundingRateHistoryServiceTestSuite) assertFundingRateHistoryEqual(e, a []*FundingRateHistory) { + r := s.r() + r.Equal(e[0].Symbol, a[0].Symbol, "Symbol") + r.Equal(e[0].FundingRate, a[0].FundingRate, "FundingRate") + r.Equal(e[0].FundingTime, a[0].FundingTime, "FundingTime") + r.Equal(e[0].MarkPrice, a[0].MarkPrice, "MarkPrice") +} diff --git a/v2/futures/funding_rate_info.go b/v2/futures/funding_rate_info.go new file mode 100644 index 00000000..1ade1231 --- /dev/null +++ b/v2/futures/funding_rate_info.go @@ -0,0 +1,42 @@ +package futures + +import ( + "context" + "encoding/json" + "net/http" + + "github.com/adshao/go-binance/v2/common" +) + +// FundingRateInfoService gets funding rate info +type FundingRateInfoService struct { + c *Client +} + +// Do sends request +func (s *FundingRateInfoService) Do(ctx context.Context, opts ...RequestOption) (res []*FundingRateInfo, err error) { + r := &request{ + method: http.MethodGet, + endpoint: "/fapi/v1/fundingInfo", + secType: secTypeNone, + } + data, _, err := s.c.callAPI(ctx, r, opts...) + data = common.ToJSONList(data) + if err != nil { + return []*FundingRateInfo{}, err + } + res = make([]*FundingRateInfo, 0) + err = json.Unmarshal(data, &res) + if err != nil { + return []*FundingRateInfo{}, err + } + return res, nil +} + +// FundingRateInfo defines funding rate info for symbols +type FundingRateInfo struct { + Symbol string `json:"symbol"` + AdjustedFundingRateCap string `json:"adjustedFundingRateCap"` + AdjustedFundingRateFloor string `json:"adjustedFundingRateFloor"` + FundingIntervalHours int64 `json:"fundingIntervalHours"` +} diff --git a/v2/futures/funding_rate_info_test.go b/v2/futures/funding_rate_info_test.go new file mode 100644 index 00000000..71e98328 --- /dev/null +++ b/v2/futures/funding_rate_info_test.go @@ -0,0 +1,50 @@ +package futures + +import ( + "github.com/stretchr/testify/suite" + "testing" +) + +type fundingRateInfoServiceTestSuite struct { + baseTestSuite +} + +func TestFundingRateInfoService(t *testing.T) { + suite.Run(t, new(fundingRateInfoServiceTestSuite)) +} + +func (s *fundingRateInfoServiceTestSuite) TestGetFundingRateInfo() { + data := []byte(`[{ + "symbol": "BTCUSDT", + "adjustedFundingRateCap": "0.02500000", + "adjustedFundingRateFloor": "-0.02500000", + "fundingIntervalHours": 8 + }]`) + s.mockDo(data, nil) + defer s.assertDo() + + s.assertReq(func(r *request) { + e := newRequest() + s.assertRequestEqual(e, r) + }) + + res, err := s.client.NewFundingRateInfoService().Do(newContext()) + s.r().NoError(err) + e := []*FundingRateInfo{ + { + Symbol: "BTCUSDT", + AdjustedFundingRateCap: "0.02500000", + AdjustedFundingRateFloor: "-0.02500000", + FundingIntervalHours: 8, + }, + } + s.assertFundingRateInfoEqual(e, res) +} + +func (s *fundingRateInfoServiceTestSuite) assertFundingRateInfoEqual(e, a []*FundingRateInfo) { + r := s.r() + r.Equal(e[0].Symbol, a[0].Symbol, "Symbol") + r.Equal(e[0].AdjustedFundingRateCap, a[0].AdjustedFundingRateCap, "AdjustedFundingRateCap") + r.Equal(e[0].AdjustedFundingRateFloor, a[0].AdjustedFundingRateFloor, "AdjustedFundingRateFloor") + r.Equal(e[0].FundingIntervalHours, a[0].FundingIntervalHours, "FundingIntervalHours") +}