exchanges/request: abstract and consolidate rate limiting code to request package (#1477)

* initial consolidation of rate limiting code to request package to reduce bespoke code implementation

* continued

* finish abstraction

* lint

* exchanges: fix tests

* linter: fix

* poloniex: fix auth rate limit not being set

* ratelimiter: convert from token to weight

* glorious: nits addressed with fire

* linter: rip

* change func name set -> get

* fix test

* derbit: impl

---------

Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io>
This commit is contained in:
Ryan O'Hara-Reid
2024-06-03 11:57:31 +10:00
committed by GitHub
parent aeb4a87913
commit f6a95da536
64 changed files with 780 additions and 2577 deletions

View File

@@ -1226,11 +1226,11 @@ func sendGetReq(path string, result interface{}) error {
if strings.Contains(path, "github") {
requester, err = request.New("Apichecker",
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(request.NewBasicRateLimit(time.Hour, 60)))
request.WithLimiter(request.NewBasicRateLimit(time.Hour, 60, 1)))
} else {
requester, err = request.New("Apichecker",
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(request.NewBasicRateLimit(time.Second, 100)))
request.WithLimiter(request.NewBasicRateLimit(time.Second, 100, 1)))
}
if err != nil {
return err
@@ -1249,7 +1249,7 @@ func sendGetReq(path string, result interface{}) error {
func sendAuthReq(method, path string, result interface{}) error {
requester, err := request.New("Apichecker",
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(request.NewBasicRateLimit(time.Second*10, 100)))
request.WithLimiter(request.NewBasicRateLimit(time.Second*10, 100, 1)))
if err != nil {
return err
}

View File

@@ -39,7 +39,7 @@ func (c *Coinmarketcap) SetDefaults() {
var err error
c.Requester, err = request.New(c.Name,
common.NewHTTPClientWithTimeout(defaultTimeOut),
request.WithLimiter(request.NewBasicRateLimit(RateInterval, BasicRequestRate)),
request.WithLimiter(request.NewBasicRateLimit(RateInterval, BasicRequestRate, 1)),
)
if err != nil {
log.Errorln(log.Global, err)

View File

@@ -26,7 +26,7 @@ func (c *CurrencyConverter) Setup(config base.Settings) error {
var err error
c.Requester, err = request.New(c.Name,
common.NewHTTPClientWithTimeout(base.DefaultTimeOut),
request.WithLimiter(request.NewBasicRateLimit(rateInterval, requestRate)))
request.WithLimiter(request.NewBasicRateLimit(rateInterval, requestRate, 1)))
return err
}

View File

@@ -32,7 +32,7 @@ func (e *ExchangeRates) Setup(config base.Settings) error {
var err error
e.Requester, err = request.New(e.Name,
common.NewHTTPClientWithTimeout(base.DefaultTimeOut),
request.WithLimiter(request.NewBasicRateLimit(rateLimitInterval, requestRate)))
request.WithLimiter(request.NewBasicRateLimit(rateLimitInterval, requestRate, 1)))
return err
}

View File

@@ -722,7 +722,7 @@ func getKlineRateBudget(limit int64) request.EndpointLimit {
rateBudget := cFuturesDefaultRate
switch {
case limit > 0 && limit < 100:
rateBudget = cFuturesKline100Rate
rateBudget = cFuturesDefaultRate
case limit >= 100 && limit < 500:
rateBudget = cFuturesKline500Rate
case limit >= 500 && limit < 1000:

View File

@@ -753,11 +753,6 @@ type UserAccountStream struct {
ListenKey string `json:"listenKey"`
}
type wsAccountInfo struct {
Stream string `json:"stream"`
Data WsAccountInfoData `json:"data"`
}
// WsAccountInfoData defines websocket account info data
type WsAccountInfoData struct {
CanDeposit bool `json:"D"`

View File

@@ -198,7 +198,7 @@ func (b *Binance) SetDefaults() {
b.Requester, err = request.New(b.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
request.WithLimiter(GetRateLimits()))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -1,12 +1,9 @@
package binance
import (
"context"
"fmt"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
const (
@@ -77,7 +74,6 @@ const (
cFuturesOrderbook100Rate
cFuturesOrderbook500Rate
cFuturesOrderbook1000Rate
cFuturesKline100Rate
cFuturesKline500Rate
cFuturesKline1000Rate
cFuturesKlineMaxRate
@@ -96,173 +92,79 @@ const (
uFuturesSetMultiAssetMarginRate
)
// RateLimit implements the request.Limiter interface
type RateLimit struct {
SpotRate *rate.Limiter
SpotOrdersRate *rate.Limiter
UFuturesRate *rate.Limiter
UFuturesOrdersRate *rate.Limiter
CFuturesRate *rate.Limiter
CFuturesOrdersRate *rate.Limiter
}
// GetRateLimits returns the rate limit for the exchange
func GetRateLimits() request.RateLimitDefinitions {
spotDefaultLimiter := request.NewRateLimit(spotInterval, spotRequestRate)
spotOrderLimiter := request.NewRateLimit(spotOrderInterval, spotOrderRequestRate)
usdMarginedFuturesLimiter := request.NewRateLimit(uFuturesInterval, uFuturesRequestRate)
usdMarginedFuturesOrdersLimiter := request.NewRateLimit(uFuturesOrderInterval, uFuturesOrderRequestRate)
coinMarginedFuturesLimiter := request.NewRateLimit(cFuturesInterval, cFuturesRequestRate)
coinMarginedFuturesOrdersLimiter := request.NewRateLimit(cFuturesOrderInterval, cFuturesOrderRequestRate)
// Limit executes rate limiting functionality for Binance
func (r *RateLimit) Limit(ctx context.Context, f request.EndpointLimit) error {
var limiter *rate.Limiter
var tokens int
switch f {
case spotDefaultRate:
limiter, tokens = r.SpotRate, 1
case spotOrderbookTickerAllRate,
spotSymbolPriceAllRate:
limiter, tokens = r.SpotRate, 2
case spotHistoricalTradesRate,
spotOrderbookDepth500Rate:
limiter, tokens = r.SpotRate, 5
case spotOrderbookDepth1000Rate,
spotAccountInformationRate,
spotExchangeInfo:
limiter, tokens = r.SpotRate, 10
case spotPriceChangeAllRate:
limiter, tokens = r.SpotRate, 40
case spotOrderbookDepth5000Rate:
limiter, tokens = r.SpotRate, 50
case spotOrderRate:
limiter, tokens = r.SpotOrdersRate, 1
case spotOrderQueryRate:
limiter, tokens = r.SpotOrdersRate, 2
case spotOpenOrdersSpecificRate:
limiter, tokens = r.SpotOrdersRate, 3
case spotAllOrdersRate:
limiter, tokens = r.SpotOrdersRate, 10
case spotOpenOrdersAllRate:
limiter, tokens = r.SpotOrdersRate, 40
case uFuturesDefaultRate,
uFuturesKline100Rate:
limiter, tokens = r.UFuturesRate, 1
case uFuturesOrderbook50Rate,
uFuturesKline500Rate,
uFuturesOrderbookTickerAllRate:
limiter, tokens = r.UFuturesRate, 2
case uFuturesOrderbook100Rate,
uFuturesKline1000Rate,
uFuturesAccountInformationRate:
limiter, tokens = r.UFuturesRate, 5
case uFuturesOrderbook500Rate,
uFuturesKlineMaxRate:
limiter, tokens = r.UFuturesRate, 10
case uFuturesOrderbook1000Rate,
uFuturesHistoricalTradesRate:
limiter, tokens = r.UFuturesRate, 20
case uFuturesTickerPriceHistoryRate:
limiter, tokens = r.UFuturesRate, 40
case uFuturesOrdersDefaultRate:
limiter, tokens = r.UFuturesOrdersRate, 1
case uFuturesBatchOrdersRate,
uFuturesGetAllOrdersRate:
limiter, tokens = r.UFuturesOrdersRate, 5
case uFuturesCountdownCancelRate:
limiter, tokens = r.UFuturesOrdersRate, 10
case uFuturesCurrencyForceOrdersRate,
uFuturesSymbolOrdersRate:
limiter, tokens = r.UFuturesOrdersRate, 20
case uFuturesIncomeHistoryRate:
limiter, tokens = r.UFuturesOrdersRate, 30
case uFuturesPairOrdersRate,
uFuturesGetAllOpenOrdersRate:
limiter, tokens = r.UFuturesOrdersRate, 40
case uFuturesAllForceOrdersRate:
limiter, tokens = r.UFuturesOrdersRate, 50
case cFuturesKline100Rate:
limiter, tokens = r.CFuturesRate, 1
case cFuturesKline500Rate,
cFuturesOrderbookTickerAllRate:
limiter, tokens = r.CFuturesRate, 2
case cFuturesKline1000Rate,
cFuturesAccountInformationRate:
limiter, tokens = r.CFuturesRate, 5
case cFuturesKlineMaxRate,
cFuturesIndexMarkPriceRate:
limiter, tokens = r.CFuturesRate, 10
case cFuturesHistoricalTradesRate,
cFuturesCurrencyForceOrdersRate:
limiter, tokens = r.CFuturesRate, 20
case cFuturesTickerPriceHistoryRate:
limiter, tokens = r.CFuturesRate, 40
case cFuturesAllForceOrdersRate:
limiter, tokens = r.CFuturesRate, 50
case cFuturesOrdersDefaultRate:
limiter, tokens = r.CFuturesOrdersRate, 1
case cFuturesBatchOrdersRate,
cFuturesGetAllOpenOrdersRate:
limiter, tokens = r.CFuturesOrdersRate, 5
case cFuturesCancelAllOrdersRate:
limiter, tokens = r.CFuturesOrdersRate, 10
case cFuturesIncomeHistoryRate,
cFuturesSymbolOrdersRate:
limiter, tokens = r.CFuturesOrdersRate, 20
case cFuturesPairOrdersRate:
limiter, tokens = r.CFuturesOrdersRate, 40
case cFuturesOrderbook50Rate:
limiter, tokens = r.CFuturesRate, 2
case cFuturesOrderbook100Rate:
limiter, tokens = r.CFuturesRate, 5
case cFuturesOrderbook500Rate:
limiter, tokens = r.CFuturesRate, 10
case cFuturesOrderbook1000Rate:
limiter, tokens = r.CFuturesRate, 20
case cFuturesDefaultRate:
limiter, tokens = r.CFuturesRate, 1
case uFuturesMultiAssetMarginRate:
limiter, tokens = r.UFuturesRate, 30
case uFuturesSetMultiAssetMarginRate:
limiter, tokens = r.UFuturesRate, 1
default:
limiter, tokens = r.SpotRate, 1
return request.RateLimitDefinitions{
spotDefaultRate: request.GetRateLimiterWithWeight(spotDefaultLimiter, 1),
spotOrderbookTickerAllRate: request.GetRateLimiterWithWeight(spotDefaultLimiter, 2),
spotSymbolPriceAllRate: request.GetRateLimiterWithWeight(spotDefaultLimiter, 2),
spotHistoricalTradesRate: request.GetRateLimiterWithWeight(spotDefaultLimiter, 5),
spotOrderbookDepth500Rate: request.GetRateLimiterWithWeight(spotDefaultLimiter, 5),
spotOrderbookDepth1000Rate: request.GetRateLimiterWithWeight(spotDefaultLimiter, 10),
spotAccountInformationRate: request.GetRateLimiterWithWeight(spotDefaultLimiter, 10),
spotExchangeInfo: request.GetRateLimiterWithWeight(spotDefaultLimiter, 10),
spotPriceChangeAllRate: request.GetRateLimiterWithWeight(spotDefaultLimiter, 40),
spotOrderbookDepth5000Rate: request.GetRateLimiterWithWeight(spotDefaultLimiter, 50),
spotOrderRate: request.GetRateLimiterWithWeight(spotOrderLimiter, 1),
spotOrderQueryRate: request.GetRateLimiterWithWeight(spotOrderLimiter, 2),
spotOpenOrdersSpecificRate: request.GetRateLimiterWithWeight(spotOrderLimiter, 3),
spotAllOrdersRate: request.GetRateLimiterWithWeight(spotOrderLimiter, 10),
spotOpenOrdersAllRate: request.GetRateLimiterWithWeight(spotOrderLimiter, 40),
uFuturesDefaultRate: request.GetRateLimiterWithWeight(usdMarginedFuturesLimiter, 1),
uFuturesKline100Rate: request.GetRateLimiterWithWeight(usdMarginedFuturesLimiter, 1),
uFuturesOrderbook50Rate: request.GetRateLimiterWithWeight(usdMarginedFuturesLimiter, 2),
uFuturesKline500Rate: request.GetRateLimiterWithWeight(usdMarginedFuturesLimiter, 2),
uFuturesOrderbookTickerAllRate: request.GetRateLimiterWithWeight(usdMarginedFuturesLimiter, 2),
uFuturesOrderbook100Rate: request.GetRateLimiterWithWeight(usdMarginedFuturesLimiter, 5),
uFuturesKline1000Rate: request.GetRateLimiterWithWeight(usdMarginedFuturesLimiter, 5),
uFuturesAccountInformationRate: request.GetRateLimiterWithWeight(usdMarginedFuturesLimiter, 5),
uFuturesOrderbook500Rate: request.GetRateLimiterWithWeight(usdMarginedFuturesLimiter, 10),
uFuturesKlineMaxRate: request.GetRateLimiterWithWeight(usdMarginedFuturesLimiter, 10),
uFuturesOrderbook1000Rate: request.GetRateLimiterWithWeight(usdMarginedFuturesLimiter, 20),
uFuturesHistoricalTradesRate: request.GetRateLimiterWithWeight(usdMarginedFuturesLimiter, 20),
uFuturesTickerPriceHistoryRate: request.GetRateLimiterWithWeight(usdMarginedFuturesLimiter, 40),
uFuturesOrdersDefaultRate: request.GetRateLimiterWithWeight(usdMarginedFuturesOrdersLimiter, 1),
uFuturesBatchOrdersRate: request.GetRateLimiterWithWeight(usdMarginedFuturesOrdersLimiter, 5),
uFuturesGetAllOrdersRate: request.GetRateLimiterWithWeight(usdMarginedFuturesOrdersLimiter, 5),
uFuturesCountdownCancelRate: request.GetRateLimiterWithWeight(usdMarginedFuturesOrdersLimiter, 10),
uFuturesCurrencyForceOrdersRate: request.GetRateLimiterWithWeight(usdMarginedFuturesOrdersLimiter, 20),
uFuturesSymbolOrdersRate: request.GetRateLimiterWithWeight(usdMarginedFuturesOrdersLimiter, 20),
uFuturesIncomeHistoryRate: request.GetRateLimiterWithWeight(usdMarginedFuturesOrdersLimiter, 30),
uFuturesPairOrdersRate: request.GetRateLimiterWithWeight(usdMarginedFuturesOrdersLimiter, 40),
uFuturesGetAllOpenOrdersRate: request.GetRateLimiterWithWeight(usdMarginedFuturesOrdersLimiter, 40),
uFuturesAllForceOrdersRate: request.GetRateLimiterWithWeight(usdMarginedFuturesOrdersLimiter, 50),
cFuturesDefaultRate: request.GetRateLimiterWithWeight(coinMarginedFuturesLimiter, 1),
cFuturesKline500Rate: request.GetRateLimiterWithWeight(coinMarginedFuturesLimiter, 2),
cFuturesOrderbookTickerAllRate: request.GetRateLimiterWithWeight(coinMarginedFuturesLimiter, 2),
cFuturesKline1000Rate: request.GetRateLimiterWithWeight(coinMarginedFuturesLimiter, 5),
cFuturesAccountInformationRate: request.GetRateLimiterWithWeight(coinMarginedFuturesLimiter, 5),
cFuturesKlineMaxRate: request.GetRateLimiterWithWeight(coinMarginedFuturesLimiter, 10),
cFuturesIndexMarkPriceRate: request.GetRateLimiterWithWeight(coinMarginedFuturesLimiter, 10),
cFuturesHistoricalTradesRate: request.GetRateLimiterWithWeight(coinMarginedFuturesLimiter, 20),
cFuturesCurrencyForceOrdersRate: request.GetRateLimiterWithWeight(coinMarginedFuturesLimiter, 20),
cFuturesTickerPriceHistoryRate: request.GetRateLimiterWithWeight(coinMarginedFuturesLimiter, 40),
cFuturesAllForceOrdersRate: request.GetRateLimiterWithWeight(coinMarginedFuturesOrdersLimiter, 50),
cFuturesOrdersDefaultRate: request.GetRateLimiterWithWeight(coinMarginedFuturesOrdersLimiter, 1),
cFuturesBatchOrdersRate: request.GetRateLimiterWithWeight(coinMarginedFuturesOrdersLimiter, 5),
cFuturesGetAllOpenOrdersRate: request.GetRateLimiterWithWeight(coinMarginedFuturesOrdersLimiter, 5),
cFuturesCancelAllOrdersRate: request.GetRateLimiterWithWeight(coinMarginedFuturesOrdersLimiter, 10),
cFuturesIncomeHistoryRate: request.GetRateLimiterWithWeight(coinMarginedFuturesOrdersLimiter, 20),
cFuturesSymbolOrdersRate: request.GetRateLimiterWithWeight(coinMarginedFuturesOrdersLimiter, 20),
cFuturesPairOrdersRate: request.GetRateLimiterWithWeight(coinMarginedFuturesOrdersLimiter, 40),
cFuturesOrderbook50Rate: request.GetRateLimiterWithWeight(coinMarginedFuturesOrdersLimiter, 2),
cFuturesOrderbook100Rate: request.GetRateLimiterWithWeight(coinMarginedFuturesOrdersLimiter, 5),
cFuturesOrderbook500Rate: request.GetRateLimiterWithWeight(coinMarginedFuturesOrdersLimiter, 10),
cFuturesOrderbook1000Rate: request.GetRateLimiterWithWeight(coinMarginedFuturesOrdersLimiter, 20),
uFuturesMultiAssetMarginRate: request.GetRateLimiterWithWeight(usdMarginedFuturesLimiter, 30),
uFuturesSetMultiAssetMarginRate: request.GetRateLimiterWithWeight(usdMarginedFuturesLimiter, 1),
}
var finalDelay time.Duration
var reserves = make([]*rate.Reservation, tokens)
for i := 0; i < tokens; i++ {
// Consume tokens 1 at a time as this avoids needing burst capacity in the limiter,
// which would otherwise allow the rate limit to be exceeded over short periods
reserves[i] = limiter.Reserve()
finalDelay = reserves[i].Delay()
}
if dl, ok := ctx.Deadline(); ok && dl.Before(time.Now().Add(finalDelay)) {
// Cancel all potential reservations to free up rate limiter if deadline
// is exceeded.
for x := range reserves {
reserves[x].Cancel()
}
return fmt.Errorf("rate limit delay of %s will exceed deadline: %w",
finalDelay,
context.DeadlineExceeded)
}
time.Sleep(finalDelay)
return nil
}
// SetRateLimit returns the rate limit for the exchange
func SetRateLimit() *RateLimit {
return &RateLimit{
SpotRate: request.NewRateLimit(spotInterval, spotRequestRate),
SpotOrdersRate: request.NewRateLimit(spotOrderInterval, spotOrderRequestRate),
UFuturesRate: request.NewRateLimit(uFuturesInterval, uFuturesRequestRate),
UFuturesOrdersRate: request.NewRateLimit(uFuturesOrderInterval, uFuturesOrderRequestRate),
CFuturesRate: request.NewRateLimit(cFuturesInterval, cFuturesRequestRate),
CFuturesOrdersRate: request.NewRateLimit(cFuturesOrderInterval, cFuturesOrderRequestRate),
}
}
func bestPriceLimit(symbol string) request.EndpointLimit {
if symbol == "" {
return spotOrderbookTickerAllRate
}
return spotDefaultRate
}
func openOrdersLimit(symbol string) request.EndpointLimit {

View File

@@ -3,9 +3,11 @@ package binance
import (
"context"
"errors"
"net/http"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
)
@@ -18,19 +20,21 @@ func TestRateLimit_Limit(t *testing.T) {
Limit request.EndpointLimit
Deadline time.Time
}{
"All Orderbooks Ticker": {Expected: spotOrderbookTickerAllRate, Limit: bestPriceLimit("")},
"Orderbook Ticker": {Expected: spotDefaultRate, Limit: bestPriceLimit(symbol)},
"Open Orders": {Expected: spotOpenOrdersSpecificRate, Limit: openOrdersLimit(symbol)},
"Orderbook Depth 5": {Expected: spotDefaultRate, Limit: orderbookLimit(5)},
"Orderbook Depth 10": {Expected: spotDefaultRate, Limit: orderbookLimit(10)},
"Orderbook Depth 20": {Expected: spotDefaultRate, Limit: orderbookLimit(20)},
"Orderbook Depth 50": {Expected: spotDefaultRate, Limit: orderbookLimit(50)},
"Orderbook Depth 100": {Expected: spotDefaultRate, Limit: orderbookLimit(100)},
"Orderbook Depth 500": {Expected: spotOrderbookDepth500Rate, Limit: orderbookLimit(500)},
"Orderbook Depth 1000": {Expected: spotOrderbookDepth1000Rate, Limit: orderbookLimit(1000)},
"Orderbook Depth 5000": {Expected: spotOrderbookDepth5000Rate, Limit: orderbookLimit(5000)},
"Exceeds deadline": {Expected: spotOrderbookDepth5000Rate, Limit: orderbookLimit(5000), Deadline: time.Now().Add(time.Nanosecond)},
"Open Orders": {Expected: spotOpenOrdersSpecificRate, Limit: openOrdersLimit(symbol)},
"Orderbook Depth 5": {Expected: spotDefaultRate, Limit: orderbookLimit(5)},
"Orderbook Depth 10": {Expected: spotDefaultRate, Limit: orderbookLimit(10)},
"Orderbook Depth 20": {Expected: spotDefaultRate, Limit: orderbookLimit(20)},
"Orderbook Depth 50": {Expected: spotDefaultRate, Limit: orderbookLimit(50)},
"Orderbook Depth 100": {Expected: spotDefaultRate, Limit: orderbookLimit(100)},
"Orderbook Depth 500": {Expected: spotOrderbookDepth500Rate, Limit: orderbookLimit(500)},
"Orderbook Depth 1000": {Expected: spotOrderbookDepth1000Rate, Limit: orderbookLimit(1000)},
"Orderbook Depth 5000": {Expected: spotOrderbookDepth5000Rate, Limit: orderbookLimit(5000)},
"Exceeds deadline": {Expected: spotOrderbookDepth5000Rate, Limit: orderbookLimit(5000), Deadline: time.Now().Add(time.Nanosecond)},
}
rl, err := request.New("rateLimitTest", &http.Client{}, request.WithLimiter(GetRateLimits()))
require.NoError(t, err)
for name, tt := range testTable {
tt := tt
t.Run(name, func(t *testing.T) {
@@ -48,8 +52,7 @@ func TestRateLimit_Limit(t *testing.T) {
defer cancel()
}
l := SetRateLimit()
if err := l.Limit(ctx, tt.Limit); err != nil && !errors.Is(err, context.DeadlineExceeded) {
if err := rl.InitiateRateLimit(ctx, tt.Limit); err != nil && !errors.Is(err, context.DeadlineExceeded) {
t.Fatalf("error applying rate limit: %v", err)
}
})
@@ -64,13 +67,16 @@ func TestRateLimit_LimitStatic(t *testing.T) {
"All Price Changes": spotPriceChangeAllRate,
"All Orders": spotAllOrdersRate,
}
rl, err := request.New("rateLimitTest2", http.DefaultClient, request.WithLimiter(GetRateLimits()))
require.NoError(t, err)
for name, tt := range testTable {
tt := tt
t.Run(name, func(t *testing.T) {
t.Parallel()
l := SetRateLimit()
if err := l.Limit(context.Background(), tt); err != nil {
if err := rl.InitiateRateLimit(context.Background(), tt); err != nil {
t.Fatalf("error applying rate limit: %v", err)
}
})

View File

@@ -325,28 +325,6 @@ func (a *WebsocketDepthStream) UnmarshalJSON(data []byte) error {
return nil
}
// UnmarshalJSON deserialises the JSON info, including the timestamp
func (a *wsAccountInfo) UnmarshalJSON(data []byte) error {
type Alias wsAccountInfo
aux := &struct {
Data struct {
EventTime binanceTime `json:"E"`
LastUpdated binanceTime `json:"u"`
*WsAccountInfoData
} `json:"data"`
*Alias
}{
Alias: (*Alias)(a),
}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
a.Data = *aux.Data.WsAccountInfoData
a.Data.EventTime = aux.Data.EventTime.Time()
a.Data.LastUpdated = aux.Data.LastUpdated.Time()
return nil
}
// UnmarshalJSON deserialises the JSON info, including the timestamp
func (a *wsAccountPosition) UnmarshalJSON(data []byte) error {
type Alias wsAccountPosition

View File

@@ -124,7 +124,7 @@ func (bi *Binanceus) SetDefaults() {
}
bi.Requester, err = request.New(bi.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
request.WithLimiter(GetRateLimit()))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -1,12 +1,9 @@
package binanceus
import (
"context"
"fmt"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
const (
@@ -41,78 +38,30 @@ const (
spotAccountInformationRate
)
// RateLimit implements the request.Limiter interface
type RateLimit struct {
SpotRate *rate.Limiter
SpotOrdersRate *rate.Limiter
}
// Limit executes rate limiting functionality for Binance
func (r *RateLimit) Limit(ctx context.Context, f request.EndpointLimit) error {
var limiter *rate.Limiter
var tokens int
switch f {
case spotDefaultRate:
limiter, tokens = r.SpotRate, 1
case spotOrderbookTickerAllRate,
spotSymbolPriceAllRate:
limiter, tokens = r.SpotRate, 2
case spotHistoricalTradesRate,
spotOrderbookDepth500Rate:
limiter, tokens = r.SpotRate, 5
case spotOrderbookDepth1000Rate,
spotAccountInformationRate,
spotExchangeInfo,
spotTradesQueryRate:
limiter, tokens = r.SpotRate, 10
case spotPriceChangeAllRate:
limiter, tokens = r.SpotRate, 40
case spotOrderbookDepth5000Rate:
limiter, tokens = r.SpotRate, 50
case spotOrderRate:
limiter, tokens = r.SpotOrdersRate, 1
case spotOrderQueryRate,
spotSingleOCOOrderRate:
limiter, tokens = r.SpotOrdersRate, 2
case spotOpenOrdersSpecificRate:
limiter, tokens = r.SpotOrdersRate, 3
case spotAllOrdersRate,
spotAllOCOOrdersRate:
limiter, tokens = r.SpotOrdersRate, 10
case spotOrderRateLimitRate:
limiter, tokens = r.SpotOrdersRate, 20
case spotOpenOrdersAllRate:
limiter, tokens = r.SpotOrdersRate, 40
default:
limiter, tokens = r.SpotRate, 1
}
var finalDelay time.Duration
var reserves = make([]*rate.Reservation, tokens)
for i := 0; i < tokens; i++ {
// Consume tokens 1 at a time as this avoids needing burst capacity in the limiter,
// which would otherwise allow the rate limit to be exceeded over short periods
reserves[i] = limiter.Reserve()
finalDelay = reserves[i].Delay()
}
if dl, ok := ctx.Deadline(); ok && dl.Before(time.Now().Add(finalDelay)) {
// Cancel all potential reservations to free up rate limiter if deadline
// is exceeded.
for x := range reserves {
reserves[x].Cancel()
}
return fmt.Errorf("rate limit delay of %s will exceed deadline: %w",
finalDelay,
context.DeadlineExceeded)
}
time.Sleep(finalDelay)
return nil
}
// SetRateLimit returns the rate limit for the exchange
func SetRateLimit() *RateLimit {
return &RateLimit{
SpotRate: request.NewRateLimit(spotInterval, spotRequestRate),
SpotOrdersRate: request.NewRateLimit(spotOrderInterval, spotOrderRequestRate),
// GetRateLimit returns the rate limit for the exchange
func GetRateLimit() request.RateLimitDefinitions {
spotRate := request.NewRateLimit(spotInterval, spotRequestRate)
spotOrdersRate := request.NewRateLimit(spotOrderInterval, spotOrderRequestRate)
return request.RateLimitDefinitions{
spotDefaultRate: request.GetRateLimiterWithWeight(spotRate, 1),
spotOrderbookTickerAllRate: request.GetRateLimiterWithWeight(spotRate, 2),
spotSymbolPriceAllRate: request.GetRateLimiterWithWeight(spotRate, 2),
spotHistoricalTradesRate: request.GetRateLimiterWithWeight(spotRate, 5),
spotOrderbookDepth500Rate: request.GetRateLimiterWithWeight(spotRate, 5),
spotOrderbookDepth1000Rate: request.GetRateLimiterWithWeight(spotRate, 10),
spotAccountInformationRate: request.GetRateLimiterWithWeight(spotRate, 10),
spotExchangeInfo: request.GetRateLimiterWithWeight(spotRate, 10),
spotTradesQueryRate: request.GetRateLimiterWithWeight(spotRate, 10),
spotPriceChangeAllRate: request.GetRateLimiterWithWeight(spotRate, 40),
spotOrderbookDepth5000Rate: request.GetRateLimiterWithWeight(spotRate, 50),
spotOrderRate: request.GetRateLimiterWithWeight(spotOrdersRate, 1),
spotOrderQueryRate: request.GetRateLimiterWithWeight(spotOrdersRate, 2),
spotSingleOCOOrderRate: request.GetRateLimiterWithWeight(spotOrdersRate, 2),
spotOpenOrdersSpecificRate: request.GetRateLimiterWithWeight(spotOrdersRate, 3),
spotAllOrdersRate: request.GetRateLimiterWithWeight(spotOrdersRate, 10),
spotAllOCOOrdersRate: request.GetRateLimiterWithWeight(spotOrdersRate, 10),
spotOrderRateLimitRate: request.GetRateLimiterWithWeight(spotOrdersRate, 20),
spotOpenOrdersAllRate: request.GetRateLimiterWithWeight(spotOrdersRate, 40),
}
}

View File

@@ -163,7 +163,7 @@ func (b *Bitfinex) SetDefaults() {
b.Requester, err = request.New(b.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
request.WithLimiter(GetRateLimit()))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -1,12 +1,9 @@
package bitfinex
import (
"context"
"errors"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
const (
@@ -175,316 +172,84 @@ const (
lends
)
// RateLimit implements the rate.Limiter interface
type RateLimit struct {
PlatformStatus *rate.Limiter
TickerBatch *rate.Limiter
Ticker *rate.Limiter
Trade *rate.Limiter
Orderbook *rate.Limiter
Stats *rate.Limiter
Candle *rate.Limiter
Configs *rate.Limiter
Status *rate.Limiter
Liquid *rate.Limiter
LeaderBoard *rate.Limiter
MarketAveragePrice *rate.Limiter
Fx *rate.Limiter
AccountWalletBalance *rate.Limiter
AccountWalletHistory *rate.Limiter
// Orders -
RetrieveOrder *rate.Limiter
SubmitOrder *rate.Limiter
UpdateOrder *rate.Limiter
CancelOrder *rate.Limiter
OrderBatch *rate.Limiter
CancelBatch *rate.Limiter
OrderHistory *rate.Limiter
GetOrderTrades *rate.Limiter
GetTrades *rate.Limiter
GetLedgers *rate.Limiter
// Positions -
GetAccountMarginInfo *rate.Limiter
GetActivePositions *rate.Limiter
ClaimPosition *rate.Limiter
GetPositionHistory *rate.Limiter
GetPositionAudit *rate.Limiter
UpdateCollateralOnPosition *rate.Limiter
// Margin funding -
GetActiveFundingOffers *rate.Limiter
SubmitFundingOffer *rate.Limiter
CancelFundingOffer *rate.Limiter
CancelAllFundingOffer *rate.Limiter
CloseFunding *rate.Limiter
FundingAutoRenew *rate.Limiter
KeepFunding *rate.Limiter
GetOffersHistory *rate.Limiter
GetFundingLoans *rate.Limiter
GetFundingLoanHistory *rate.Limiter
GetFundingCredits *rate.Limiter
GetFundingCreditsHistory *rate.Limiter
GetFundingTrades *rate.Limiter
GetFundingInfo *rate.Limiter
// Account actions
GetUserInfo *rate.Limiter
TransferBetweenWallets *rate.Limiter
GetDepositAddress *rate.Limiter
Withdrawal *rate.Limiter
GetMovements *rate.Limiter
GetAlertList *rate.Limiter
SetPriceAlert *rate.Limiter
DeletePriceAlert *rate.Limiter
GetBalanceForOrdersOffers *rate.Limiter
UserSettingsWrite *rate.Limiter
UserSettingsRead *rate.Limiter
UserSettingsDelete *rate.Limiter
// Account V1 endpoints
GetAccountFees *rate.Limiter
GetWithdrawalFees *rate.Limiter
GetAccountSummary *rate.Limiter
NewDepositAddress *rate.Limiter
GetKeyPermissions *rate.Limiter
GetMarginInfo *rate.Limiter
GetAccountBalance *rate.Limiter
WalletTransfer *rate.Limiter
WithdrawV1 *rate.Limiter
OrderV1 *rate.Limiter
OrderMulti *rate.Limiter
StatsV1 *rate.Limiter
Fundingbook *rate.Limiter
Lends *rate.Limiter
}
// Limit limits outbound requests
func (r *RateLimit) Limit(ctx context.Context, f request.EndpointLimit) error {
switch f {
case platformStatus:
return r.PlatformStatus.Wait(ctx)
case tickerBatch:
return r.TickerBatch.Wait(ctx)
case tickerFunction:
return r.Ticker.Wait(ctx)
case tradeRateLimit:
return r.Trade.Wait(ctx)
case orderbookFunction:
return r.Orderbook.Wait(ctx)
case stats:
return r.Stats.Wait(ctx)
case candle:
return r.Candle.Wait(ctx)
case configs:
return r.Configs.Wait(ctx)
case status:
return r.Stats.Wait(ctx)
case liquid:
return r.Liquid.Wait(ctx)
case leaderBoard:
return r.LeaderBoard.Wait(ctx)
case marketAveragePrice:
return r.MarketAveragePrice.Wait(ctx)
case fx:
return r.Fx.Wait(ctx)
case accountWalletBalance:
return r.AccountWalletBalance.Wait(ctx)
case accountWalletHistory:
return r.AccountWalletHistory.Wait(ctx)
case retrieveOrder:
return r.RetrieveOrder.Wait(ctx)
case submitOrder:
return r.SubmitOrder.Wait(ctx)
case updateOrder:
return r.UpdateOrder.Wait(ctx)
case cancelOrder:
return r.CancelOrder.Wait(ctx)
case orderBatch:
return r.OrderBatch.Wait(ctx)
case cancelBatch:
return r.CancelBatch.Wait(ctx)
case orderHistory:
return r.OrderHistory.Wait(ctx)
case getOrderTrades:
return r.GetOrderTrades.Wait(ctx)
case getTrades:
return r.GetTrades.Wait(ctx)
case getLedgers:
return r.GetLedgers.Wait(ctx)
case getAccountMarginInfo:
return r.GetAccountMarginInfo.Wait(ctx)
case getActivePositions:
return r.GetActivePositions.Wait(ctx)
case claimPosition:
return r.ClaimPosition.Wait(ctx)
case getPositionHistory:
return r.GetPositionHistory.Wait(ctx)
case getPositionAudit:
return r.GetPositionAudit.Wait(ctx)
case updateCollateralOnPosition:
return r.UpdateCollateralOnPosition.Wait(ctx)
case getActiveFundingOffers:
return r.GetActiveFundingOffers.Wait(ctx)
case submitFundingOffer:
return r.SubmitFundingOffer.Wait(ctx)
case cancelFundingOffer:
return r.CancelFundingOffer.Wait(ctx)
case cancelAllFundingOffer:
return r.CancelAllFundingOffer.Wait(ctx)
case closeFunding:
return r.CloseFunding.Wait(ctx)
case fundingAutoRenew:
return r.FundingAutoRenew.Wait(ctx)
case keepFunding:
return r.KeepFunding.Wait(ctx)
case getOffersHistory:
return r.GetOffersHistory.Wait(ctx)
case getFundingLoans:
return r.GetFundingLoans.Wait(ctx)
case getFundingLoanHistory:
return r.GetFundingLoanHistory.Wait(ctx)
case getFundingCredits:
return r.GetFundingCredits.Wait(ctx)
case getFundingCreditsHistory:
return r.GetFundingCreditsHistory.Wait(ctx)
case getFundingTrades:
return r.GetFundingTrades.Wait(ctx)
case getFundingInfo:
return r.GetFundingInfo.Wait(ctx)
case getUserInfo:
return r.GetUserInfo.Wait(ctx)
case transferBetweenWallets:
return r.TransferBetweenWallets.Wait(ctx)
case getDepositAddress:
return r.GetDepositAddress.Wait(ctx)
case withdrawal:
return r.Withdrawal.Wait(ctx)
case getMovements:
return r.GetMovements.Wait(ctx)
case getAlertList:
return r.GetAlertList.Wait(ctx)
case setPriceAlert:
return r.SetPriceAlert.Wait(ctx)
case deletePriceAlert:
return r.DeletePriceAlert.Wait(ctx)
case getBalanceForOrdersOffers:
return r.GetBalanceForOrdersOffers.Wait(ctx)
case userSettingsWrite:
return r.UserSettingsWrite.Wait(ctx)
case userSettingsRead:
return r.UserSettingsRead.Wait(ctx)
case userSettingsDelete:
return r.UserSettingsDelete.Wait(ctx)
// Bitfinex V1 API
case getAccountFees:
return r.GetAccountFees.Wait(ctx)
case getWithdrawalFees:
return r.GetWithdrawalFees.Wait(ctx)
case getAccountSummary:
return r.GetAccountSummary.Wait(ctx)
case newDepositAddress:
return r.NewDepositAddress.Wait(ctx)
case getKeyPermissions:
return r.GetKeyPermissions.Wait(ctx)
case getMarginInfo:
return r.GetMarginInfo.Wait(ctx)
case getAccountBalance:
return r.GetAccountBalance.Wait(ctx)
case walletTransfer:
return r.WalletTransfer.Wait(ctx)
case withdrawV1:
return r.WithdrawV1.Wait(ctx)
case orderV1:
return r.OrderV1.Wait(ctx)
case orderMulti:
return r.OrderMulti.Wait(ctx)
case statsV1:
return r.Stats.Wait(ctx)
case fundingbook:
return r.Fundingbook.Wait(ctx)
case lends:
return r.Lends.Wait(ctx)
default:
return errors.New("endpoint rate limit functionality not found")
}
}
// SetRateLimit returns the rate limit for the exchange
func SetRateLimit() *RateLimit {
return &RateLimit{
PlatformStatus: request.NewRateLimit(requestLimitInterval, platformStatusReqRate),
TickerBatch: request.NewRateLimit(requestLimitInterval, tickerBatchReqRate),
Ticker: request.NewRateLimit(requestLimitInterval, tickerReqRate),
Trade: request.NewRateLimit(requestLimitInterval, tradeReqRate),
Orderbook: request.NewRateLimit(requestLimitInterval, orderbookReqRate),
Stats: request.NewRateLimit(requestLimitInterval, statsReqRate),
Candle: request.NewRateLimit(requestLimitInterval, candleReqRate),
Configs: request.NewRateLimit(requestLimitInterval, configsReqRate),
Status: request.NewRateLimit(requestLimitInterval, statusReqRate),
Liquid: request.NewRateLimit(requestLimitInterval, liquidReqRate),
LeaderBoard: request.NewRateLimit(requestLimitInterval, leaderBoardReqRate),
MarketAveragePrice: request.NewRateLimit(requestLimitInterval, marketAveragePriceReqRate),
Fx: request.NewRateLimit(requestLimitInterval, fxReqRate),
AccountWalletBalance: request.NewRateLimit(requestLimitInterval, accountWalletBalanceReqRate),
AccountWalletHistory: request.NewRateLimit(requestLimitInterval, accountWalletHistoryReqRate),
// GetRateLimit returns the rate limit for the exchange
func GetRateLimit() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
platformStatus: request.NewRateLimitWithWeight(requestLimitInterval, platformStatusReqRate, 1),
tickerBatch: request.NewRateLimitWithWeight(requestLimitInterval, tickerBatchReqRate, 1),
tickerFunction: request.NewRateLimitWithWeight(requestLimitInterval, tickerReqRate, 1),
tradeRateLimit: request.NewRateLimitWithWeight(requestLimitInterval, tradeReqRate, 1),
orderbookFunction: request.NewRateLimitWithWeight(requestLimitInterval, orderbookReqRate, 1),
stats: request.NewRateLimitWithWeight(requestLimitInterval, statsReqRate, 1),
candle: request.NewRateLimitWithWeight(requestLimitInterval, candleReqRate, 1),
configs: request.NewRateLimitWithWeight(requestLimitInterval, configsReqRate, 1),
status: request.NewRateLimitWithWeight(requestLimitInterval, statusReqRate, 1),
liquid: request.NewRateLimitWithWeight(requestLimitInterval, liquidReqRate, 1),
leaderBoard: request.NewRateLimitWithWeight(requestLimitInterval, leaderBoardReqRate, 1),
marketAveragePrice: request.NewRateLimitWithWeight(requestLimitInterval, marketAveragePriceReqRate, 1),
fx: request.NewRateLimitWithWeight(requestLimitInterval, fxReqRate, 1),
accountWalletBalance: request.NewRateLimitWithWeight(requestLimitInterval, accountWalletBalanceReqRate, 1),
accountWalletHistory: request.NewRateLimitWithWeight(requestLimitInterval, accountWalletHistoryReqRate, 1),
// Orders -
RetrieveOrder: request.NewRateLimit(requestLimitInterval, retrieveOrderReqRate),
SubmitOrder: request.NewRateLimit(requestLimitInterval, submitOrderReqRate),
UpdateOrder: request.NewRateLimit(requestLimitInterval, updateOrderReqRate),
CancelOrder: request.NewRateLimit(requestLimitInterval, cancelOrderReqRate),
OrderBatch: request.NewRateLimit(requestLimitInterval, orderBatchReqRate),
CancelBatch: request.NewRateLimit(requestLimitInterval, cancelBatchReqRate),
OrderHistory: request.NewRateLimit(requestLimitInterval, orderHistoryReqRate),
GetOrderTrades: request.NewRateLimit(requestLimitInterval, getOrderTradesReqRate),
GetTrades: request.NewRateLimit(requestLimitInterval, getTradesReqRate),
GetLedgers: request.NewRateLimit(requestLimitInterval, getLedgersReqRate),
retrieveOrder: request.NewRateLimitWithWeight(requestLimitInterval, retrieveOrderReqRate, 1),
submitOrder: request.NewRateLimitWithWeight(requestLimitInterval, submitOrderReqRate, 1),
updateOrder: request.NewRateLimitWithWeight(requestLimitInterval, updateOrderReqRate, 1),
cancelOrder: request.NewRateLimitWithWeight(requestLimitInterval, cancelOrderReqRate, 1),
orderBatch: request.NewRateLimitWithWeight(requestLimitInterval, orderBatchReqRate, 1),
cancelBatch: request.NewRateLimitWithWeight(requestLimitInterval, cancelBatchReqRate, 1),
orderHistory: request.NewRateLimitWithWeight(requestLimitInterval, orderHistoryReqRate, 1),
getOrderTrades: request.NewRateLimitWithWeight(requestLimitInterval, getOrderTradesReqRate, 1),
getTrades: request.NewRateLimitWithWeight(requestLimitInterval, getTradesReqRate, 1),
getLedgers: request.NewRateLimitWithWeight(requestLimitInterval, getLedgersReqRate, 1),
// Positions -
GetAccountMarginInfo: request.NewRateLimit(requestLimitInterval, getAccountMarginInfoReqRate),
GetActivePositions: request.NewRateLimit(requestLimitInterval, getActivePositionsReqRate),
ClaimPosition: request.NewRateLimit(requestLimitInterval, claimPositionReqRate),
GetPositionHistory: request.NewRateLimit(requestLimitInterval, getPositionAuditReqRate),
GetPositionAudit: request.NewRateLimit(requestLimitInterval, getPositionAuditReqRate),
UpdateCollateralOnPosition: request.NewRateLimit(requestLimitInterval, updateCollateralOnPositionReqRate),
getAccountMarginInfo: request.NewRateLimitWithWeight(requestLimitInterval, getAccountMarginInfoReqRate, 1),
getActivePositions: request.NewRateLimitWithWeight(requestLimitInterval, getActivePositionsReqRate, 1),
claimPosition: request.NewRateLimitWithWeight(requestLimitInterval, claimPositionReqRate, 1),
getPositionHistory: request.NewRateLimitWithWeight(requestLimitInterval, getPositionAuditReqRate, 1),
getPositionAudit: request.NewRateLimitWithWeight(requestLimitInterval, getPositionAuditReqRate, 1),
updateCollateralOnPosition: request.NewRateLimitWithWeight(requestLimitInterval, updateCollateralOnPositionReqRate, 1),
// Margin funding -
GetActiveFundingOffers: request.NewRateLimit(requestLimitInterval, getActiveFundingOffersReqRate),
SubmitFundingOffer: request.NewRateLimit(requestLimitInterval, submitFundingOfferReqRate),
CancelFundingOffer: request.NewRateLimit(requestLimitInterval, cancelFundingOfferReqRate),
CancelAllFundingOffer: request.NewRateLimit(requestLimitInterval, cancelAllFundingOfferReqRate),
CloseFunding: request.NewRateLimit(requestLimitInterval, closeFundingReqRate),
FundingAutoRenew: request.NewRateLimit(requestLimitInterval, fundingAutoRenewReqRate),
KeepFunding: request.NewRateLimit(requestLimitInterval, keepFundingReqRate),
GetOffersHistory: request.NewRateLimit(requestLimitInterval, getOffersHistoryReqRate),
GetFundingLoans: request.NewRateLimit(requestLimitInterval, getOffersHistoryReqRate),
GetFundingLoanHistory: request.NewRateLimit(requestLimitInterval, getFundingLoanHistoryReqRate),
GetFundingCredits: request.NewRateLimit(requestLimitInterval, getFundingCreditsReqRate),
GetFundingCreditsHistory: request.NewRateLimit(requestLimitInterval, getFundingCreditsHistoryReqRate),
GetFundingTrades: request.NewRateLimit(requestLimitInterval, getFundingTradesReqRate),
GetFundingInfo: request.NewRateLimit(requestLimitInterval, getFundingInfoReqRate),
getActiveFundingOffers: request.NewRateLimitWithWeight(requestLimitInterval, getActiveFundingOffersReqRate, 1),
submitFundingOffer: request.NewRateLimitWithWeight(requestLimitInterval, submitFundingOfferReqRate, 1),
cancelFundingOffer: request.NewRateLimitWithWeight(requestLimitInterval, cancelFundingOfferReqRate, 1),
cancelAllFundingOffer: request.NewRateLimitWithWeight(requestLimitInterval, cancelAllFundingOfferReqRate, 1),
closeFunding: request.NewRateLimitWithWeight(requestLimitInterval, closeFundingReqRate, 1),
fundingAutoRenew: request.NewRateLimitWithWeight(requestLimitInterval, fundingAutoRenewReqRate, 1),
keepFunding: request.NewRateLimitWithWeight(requestLimitInterval, keepFundingReqRate, 1),
getOffersHistory: request.NewRateLimitWithWeight(requestLimitInterval, getOffersHistoryReqRate, 1),
getFundingLoans: request.NewRateLimitWithWeight(requestLimitInterval, getOffersHistoryReqRate, 1),
getFundingLoanHistory: request.NewRateLimitWithWeight(requestLimitInterval, getFundingLoanHistoryReqRate, 1),
getFundingCredits: request.NewRateLimitWithWeight(requestLimitInterval, getFundingCreditsReqRate, 1),
getFundingCreditsHistory: request.NewRateLimitWithWeight(requestLimitInterval, getFundingCreditsHistoryReqRate, 1),
getFundingTrades: request.NewRateLimitWithWeight(requestLimitInterval, getFundingTradesReqRate, 1),
getFundingInfo: request.NewRateLimitWithWeight(requestLimitInterval, getFundingInfoReqRate, 1),
// Account actions
GetUserInfo: request.NewRateLimit(requestLimitInterval, getUserInfoReqRate),
TransferBetweenWallets: request.NewRateLimit(requestLimitInterval, transferBetweenWalletsReqRate),
GetDepositAddress: request.NewRateLimit(requestLimitInterval, getDepositAddressReqRate),
Withdrawal: request.NewRateLimit(requestLimitInterval, withdrawalReqRate),
GetMovements: request.NewRateLimit(requestLimitInterval, getMovementsReqRate),
GetAlertList: request.NewRateLimit(requestLimitInterval, getAlertListReqRate),
SetPriceAlert: request.NewRateLimit(requestLimitInterval, setPriceAlertReqRate),
DeletePriceAlert: request.NewRateLimit(requestLimitInterval, deletePriceAlertReqRate),
GetBalanceForOrdersOffers: request.NewRateLimit(requestLimitInterval, getBalanceForOrdersOffersReqRate),
UserSettingsWrite: request.NewRateLimit(requestLimitInterval, userSettingsWriteReqRate),
UserSettingsRead: request.NewRateLimit(requestLimitInterval, userSettingsReadReqRate),
UserSettingsDelete: request.NewRateLimit(requestLimitInterval, userSettingsDeleteReqRate),
getUserInfo: request.NewRateLimitWithWeight(requestLimitInterval, getUserInfoReqRate, 1),
transferBetweenWallets: request.NewRateLimitWithWeight(requestLimitInterval, transferBetweenWalletsReqRate, 1),
getDepositAddress: request.NewRateLimitWithWeight(requestLimitInterval, getDepositAddressReqRate, 1),
withdrawal: request.NewRateLimitWithWeight(requestLimitInterval, withdrawalReqRate, 1),
getMovements: request.NewRateLimitWithWeight(requestLimitInterval, getMovementsReqRate, 1),
getAlertList: request.NewRateLimitWithWeight(requestLimitInterval, getAlertListReqRate, 1),
setPriceAlert: request.NewRateLimitWithWeight(requestLimitInterval, setPriceAlertReqRate, 1),
deletePriceAlert: request.NewRateLimitWithWeight(requestLimitInterval, deletePriceAlertReqRate, 1),
getBalanceForOrdersOffers: request.NewRateLimitWithWeight(requestLimitInterval, getBalanceForOrdersOffersReqRate, 1),
userSettingsWrite: request.NewRateLimitWithWeight(requestLimitInterval, userSettingsWriteReqRate, 1),
userSettingsRead: request.NewRateLimitWithWeight(requestLimitInterval, userSettingsReadReqRate, 1),
userSettingsDelete: request.NewRateLimitWithWeight(requestLimitInterval, userSettingsDeleteReqRate, 1),
// Account V1 endpoints
GetAccountFees: request.NewRateLimit(requestLimitInterval, getAccountFeesReqRate),
GetWithdrawalFees: request.NewRateLimit(requestLimitInterval, getWithdrawalFeesReqRate),
GetAccountSummary: request.NewRateLimit(requestLimitInterval, getAccountSummaryReqRate),
NewDepositAddress: request.NewRateLimit(requestLimitInterval, newDepositAddressReqRate),
GetKeyPermissions: request.NewRateLimit(requestLimitInterval, getKeyPermissionsReqRate),
GetMarginInfo: request.NewRateLimit(requestLimitInterval, getMarginInfoReqRate),
GetAccountBalance: request.NewRateLimit(requestLimitInterval, getAccountBalanceReqRate),
WalletTransfer: request.NewRateLimit(requestLimitInterval, walletTransferReqRate),
WithdrawV1: request.NewRateLimit(requestLimitInterval, withdrawV1ReqRate),
OrderV1: request.NewRateLimit(requestLimitInterval, orderV1ReqRate),
OrderMulti: request.NewRateLimit(requestLimitInterval, orderMultiReqRate),
StatsV1: request.NewRateLimit(requestLimitInterval, statsV1ReqRate),
Fundingbook: request.NewRateLimit(requestLimitInterval, fundingbookReqRate),
Lends: request.NewRateLimit(requestLimitInterval, lendsReqRate),
getAccountFees: request.NewRateLimitWithWeight(requestLimitInterval, getAccountFeesReqRate, 1),
getWithdrawalFees: request.NewRateLimitWithWeight(requestLimitInterval, getWithdrawalFeesReqRate, 1),
getAccountSummary: request.NewRateLimitWithWeight(requestLimitInterval, getAccountSummaryReqRate, 1),
newDepositAddress: request.NewRateLimitWithWeight(requestLimitInterval, newDepositAddressReqRate, 1),
getKeyPermissions: request.NewRateLimitWithWeight(requestLimitInterval, getKeyPermissionsReqRate, 1),
getMarginInfo: request.NewRateLimitWithWeight(requestLimitInterval, getMarginInfoReqRate, 1),
getAccountBalance: request.NewRateLimitWithWeight(requestLimitInterval, getAccountBalanceReqRate, 1),
walletTransfer: request.NewRateLimitWithWeight(requestLimitInterval, walletTransferReqRate, 1),
withdrawV1: request.NewRateLimitWithWeight(requestLimitInterval, withdrawV1ReqRate, 1),
orderV1: request.NewRateLimitWithWeight(requestLimitInterval, orderV1ReqRate, 1),
orderMulti: request.NewRateLimitWithWeight(requestLimitInterval, orderMultiReqRate, 1),
statsV1: request.NewRateLimitWithWeight(requestLimitInterval, statsV1ReqRate, 1),
fundingbook: request.NewRateLimitWithWeight(requestLimitInterval, fundingbookReqRate, 1),
lends: request.NewRateLimitWithWeight(requestLimitInterval, lendsReqRate, 1),
}
}

View File

@@ -300,7 +300,7 @@ func (b *Bitflyer) SendHTTPRequest(ctx context.Context, ep exchange.URL, path st
HTTPDebugging: b.HTTPDebugging,
HTTPRecording: b.HTTPRecording,
}
return b.SendPayload(ctx, request.Unset, func() (*request.Item, error) {
return b.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) {
return item, nil
}, request.UnauthenticatedRequest)
}

View File

@@ -74,7 +74,7 @@ func (b *Bitflyer) SetDefaults() {
b.Requester, err = request.New(b.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
request.WithLimiter(GetRateLimit()))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -1,11 +1,9 @@
package bitflyer
import (
"context"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
// Exchange specific rate limit consts
@@ -17,50 +15,14 @@ const (
bitflyerPublicRequestRate = 500
)
// RateLimit implements the rate.Limiter interface
type RateLimit struct {
Auth *rate.Limiter
UnAuth *rate.Limiter
// Send a New Order
// Submit New Parent Order (Special order)
// Cancel All Orders
Order *rate.Limiter
LowVolume *rate.Limiter
}
// Limit limits outbound requests
func (r *RateLimit) Limit(ctx context.Context, f request.EndpointLimit) error {
switch f {
case request.Auth:
return r.Auth.Wait(ctx)
case orders:
err := r.Auth.Wait(ctx)
if err != nil {
return err
}
return r.Order.Wait(ctx)
case lowVolume:
err := r.LowVolume.Wait(ctx)
if err != nil {
return err
}
err = r.Order.Wait(ctx)
if err != nil {
return err
}
return r.Auth.Wait(ctx)
default:
return r.UnAuth.Wait(ctx)
}
}
// SetRateLimit returns the rate limit for the exchange
func SetRateLimit() *RateLimit {
return &RateLimit{
Auth: request.NewRateLimit(biflyerRateInterval, bitflyerPrivateRequestRate),
UnAuth: request.NewRateLimit(biflyerRateInterval, bitflyerPublicRequestRate),
Order: request.NewRateLimit(biflyerRateInterval, bitflyerPrivateSendOrderRequestRate),
LowVolume: request.NewRateLimit(time.Minute, bitflyerPrivateLowVolumeRequestRate),
// GetRateLimit returns the rate limit for the exchange
func GetRateLimit() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
request.Auth: request.NewRateLimitWithWeight(biflyerRateInterval, bitflyerPrivateRequestRate, 1),
request.UnAuth: request.NewRateLimitWithWeight(biflyerRateInterval, bitflyerPublicRequestRate, 1),
// TODO: Below limits need to also take from auth rate limit. This
// can not yet be tested and verified so is left not done for now.
orders: request.NewRateLimitWithWeight(biflyerRateInterval, bitflyerPrivateSendOrderRequestRate, 1),
lowVolume: request.NewRateLimitWithWeight(time.Minute, bitflyerPrivateLowVolumeRequestRate, 1),
}
}

View File

@@ -114,7 +114,7 @@ func (b *Bithumb) SetDefaults() {
}
b.Requester, err = request.New(b.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
request.WithLimiter(GetRateLimit()))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -1,11 +1,9 @@
package bithumb
import (
"context"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
// Exchange specific rate limit consts
@@ -15,24 +13,10 @@ const (
bithumbUnauthRate = 95
)
// RateLimit implements the request.Limiter interface
type RateLimit struct {
Auth *rate.Limiter
UnAuth *rate.Limiter
}
// Limit limits requests
func (r *RateLimit) Limit(ctx context.Context, f request.EndpointLimit) error {
if f == request.Auth {
return r.Auth.Wait(ctx)
}
return r.UnAuth.Wait(ctx)
}
// SetRateLimit returns the rate limit for the exchange
func SetRateLimit() *RateLimit {
return &RateLimit{
Auth: request.NewRateLimit(bithumbRateInterval, bithumbAuthRate),
UnAuth: request.NewRateLimit(bithumbRateInterval, bithumbUnauthRate),
// GetRateLimit returns the rate limit for the exchange
func GetRateLimit() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
request.Auth: request.NewRateLimitWithWeight(bithumbRateInterval, bithumbAuthRate, 1),
request.Unset: request.NewRateLimitWithWeight(bithumbRateInterval, bithumbUnauthRate, 1),
}
}

View File

@@ -860,7 +860,7 @@ func (b *Bitmex) SendHTTPRequest(ctx context.Context, ep exchange.URL, path stri
HTTPRecording: b.HTTPRecording,
}
err = b.SendPayload(ctx, request.Unset, func() (*request.Item, error) {
err = b.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) {
return item, nil
}, request.UnauthenticatedRequest)
if err != nil {

View File

@@ -140,7 +140,7 @@ func (b *Bitmex) SetDefaults() {
b.Requester, err = request.New(b.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
request.WithLimiter(GetRateLimit()))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -1,11 +1,9 @@
package bitmex
import (
"context"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
// Bitmex rate limits
@@ -15,24 +13,10 @@ const (
bitmexAuthRate = 60
)
// RateLimit implements the request.Limiter interface
type RateLimit struct {
Auth *rate.Limiter
UnAuth *rate.Limiter
}
// Limit limits outbound calls
func (r *RateLimit) Limit(ctx context.Context, f request.EndpointLimit) error {
if f == request.Auth {
return r.Auth.Wait(ctx)
}
return r.UnAuth.Wait(ctx)
}
// SetRateLimit returns the rate limit for the exchange
func SetRateLimit() *RateLimit {
return &RateLimit{
Auth: request.NewRateLimit(bitmexRateInterval, bitmexAuthRate),
UnAuth: request.NewRateLimit(bitmexRateInterval, bitmexUnauthRate),
// GetRateLimit returns the rate limit for the exchange
func GetRateLimit() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
request.Auth: request.NewRateLimitWithWeight(bitmexRateInterval, bitmexAuthRate, 1),
request.UnAuth: request.NewRateLimitWithWeight(bitmexRateInterval, bitmexUnauthRate, 1),
}
}

View File

@@ -111,7 +111,7 @@ func (b *Bitstamp) SetDefaults() {
b.Requester, err = request.New(b.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(request.NewBasicRateLimit(bitstampRateInterval, bitstampRequestRate)))
request.WithLimiter(request.NewBasicRateLimit(bitstampRateInterval, bitstampRequestRate, 1)))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -814,7 +814,7 @@ func (b *BTCMarkets) SendHTTPRequest(ctx context.Context, path string, result in
HTTPDebugging: b.HTTPDebugging,
HTTPRecording: b.HTTPRecording,
}
return b.SendPayload(ctx, request.Unset, func() (*request.Item, error) {
return b.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) {
return item, nil
}, request.UnauthenticatedRequest)
}

View File

@@ -115,7 +115,7 @@ func (b *BTCMarkets) SetDefaults() {
b.Requester, err = request.New(b.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
request.WithLimiter(GetRateLimit()))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -1,11 +1,9 @@
package btcmarkets
import (
"context"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
// BTCMarkets Rate limit consts
@@ -25,42 +23,14 @@ const (
newReportFunc
)
// RateLimit implements the request.Limiter interface
type RateLimit struct {
Auth *rate.Limiter
UnAuth *rate.Limiter
OrderPlacement *rate.Limiter
BatchOrders *rate.Limiter
WithdrawRequest *rate.Limiter
CreateNewReport *rate.Limiter
}
// Limit limits the outbound requests
func (r *RateLimit) Limit(ctx context.Context, f request.EndpointLimit) error {
switch f {
case request.Auth:
return r.Auth.Wait(ctx)
case orderFunc:
return r.OrderPlacement.Wait(ctx)
case batchFunc:
return r.BatchOrders.Wait(ctx)
case withdrawFunc:
return r.WithdrawRequest.Wait(ctx)
case newReportFunc:
return r.CreateNewReport.Wait(ctx)
default:
return r.UnAuth.Wait(ctx)
}
}
// SetRateLimit returns the rate limit for the exchange
func SetRateLimit() *RateLimit {
return &RateLimit{
Auth: request.NewRateLimit(btcmarketsRateInterval, btcmarketsAuthLimit),
UnAuth: request.NewRateLimit(btcmarketsRateInterval, btcmarketsUnauthLimit),
OrderPlacement: request.NewRateLimit(btcmarketsRateInterval, btcmarketsOrderLimit),
BatchOrders: request.NewRateLimit(btcmarketsRateInterval, btcmarketsBatchOrderLimit),
WithdrawRequest: request.NewRateLimit(btcmarketsRateInterval, btcmarketsWithdrawLimit),
CreateNewReport: request.NewRateLimit(btcmarketsRateInterval, btcmarketsCreateNewReportLimit),
// GetRateLimit returns the rate limit for the exchange
func GetRateLimit() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
request.Auth: request.NewRateLimitWithWeight(btcmarketsRateInterval, btcmarketsAuthLimit, 1),
request.UnAuth: request.NewRateLimitWithWeight(btcmarketsRateInterval, btcmarketsUnauthLimit, 1),
orderFunc: request.NewRateLimitWithWeight(btcmarketsRateInterval, btcmarketsOrderLimit, 1),
batchFunc: request.NewRateLimitWithWeight(btcmarketsRateInterval, btcmarketsBatchOrderLimit, 1),
withdrawFunc: request.NewRateLimitWithWeight(btcmarketsRateInterval, btcmarketsWithdrawLimit, 1),
newReportFunc: request.NewRateLimitWithWeight(btcmarketsRateInterval, btcmarketsCreateNewReportLimit, 1),
}
}

View File

@@ -140,7 +140,7 @@ func (b *BTSE) SetDefaults() {
b.Requester, err = request.New(b.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
request.WithLimiter(GetRateLimit()))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -1,11 +1,9 @@
package btse
import (
"context"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
const (
@@ -17,26 +15,10 @@ const (
orderFunc
)
// RateLimit implements the request.Limiter interface
type RateLimit struct {
Query *rate.Limiter
Orders *rate.Limiter
}
// Limit executes rate limiting functionality for exchange
func (r *RateLimit) Limit(ctx context.Context, f request.EndpointLimit) error {
switch f {
case orderFunc:
return r.Orders.Wait(ctx)
default:
return r.Query.Wait(ctx)
}
}
// SetRateLimit returns the rate limit for the exchange
func SetRateLimit() *RateLimit {
return &RateLimit{
Orders: request.NewRateLimit(btseRateInterval, btseOrdersLimit),
Query: request.NewRateLimit(btseRateInterval, btseQueryLimit),
// GetRateLimit returns the rate limit for the exchange
func GetRateLimit() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
orderFunc: request.NewRateLimitWithWeight(btseRateInterval, btseOrdersLimit, 1),
queryFunc: request.NewRateLimitWithWeight(btseRateInterval, btseQueryLimit, 1),
}
}

View File

@@ -178,7 +178,7 @@ func (by *Bybit) SetDefaults() {
by.Requester, err = request.New(by.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
request.WithLimiter(GetRateLimit()))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -1,17 +1,9 @@
package bybit
import (
"context"
"fmt"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
const (
// See: https://bybit-exchange.github.io/docs/v5/rate-limit
spotInterval = time.Second * 5
)
const (
@@ -76,281 +68,67 @@ const (
spotCrossMarginTradeSwitchEPL
)
// RateLimit implements the request.Limiter interface
type RateLimit struct {
SpotRate *rate.Limiter
CreateOrderRate *rate.Limiter
CreateSpotOrderRate *rate.Limiter
AmendOrderRate *rate.Limiter
CancelOrderRate *rate.Limiter
CancelSpotRate *rate.Limiter
CancelAllRate *rate.Limiter
CancelAllSpotRate *rate.Limiter
CreateBatchOrderRate *rate.Limiter
AmendBatchOrderRate *rate.Limiter
CancelBatchOrderRate *rate.Limiter
GetOrderRate *rate.Limiter
GetOrderHistoryRate *rate.Limiter
GetPositionListRate *rate.Limiter
GetExecutionListRate *rate.Limiter
GetPositionClosedPNLRate *rate.Limiter
PostPositionSetLeverageRate *rate.Limiter
SetPositionTPLSModeRate *rate.Limiter
SetPositionRiskLimitRate *rate.Limiter
StopTradingPositionRate *rate.Limiter
GetAccountWalletBalanceRate *rate.Limiter
GetAccountFeeRate *rate.Limiter
GetAssetTransferQueryInfoRate *rate.Limiter
GetAssetTransferQueryTransferCoinListRate *rate.Limiter
GetAssetTransferCoinListRate *rate.Limiter
GetAssetInterTransferListRate *rate.Limiter
GetSubMemberListRate *rate.Limiter
GetAssetUniversalTransferListRate *rate.Limiter
GetAssetAccountCoinBalanceRate *rate.Limiter
GetAssetDepositRecordsRate *rate.Limiter
GetAssetDepositSubMemberRecordsRate *rate.Limiter
GetAssetDepositSubMemberAddressRate *rate.Limiter
GetWithdrawRecordsRate *rate.Limiter
GetAssetCoinInfoRate *rate.Limiter
GetExchangeOrderRecordRate *rate.Limiter
InterTransferRate *rate.Limiter
SaveTransferSubMemberRate *rate.Limiter
UniversalTransferRate *rate.Limiter
CreateWithdrawalRate *rate.Limiter
CancelWithdrawalRate *rate.Limiter
UserCreateSubMemberRate *rate.Limiter
UserCreateSubAPIKeyRate *rate.Limiter
UserFrozenSubMemberRate *rate.Limiter
UserUpdateAPIRate *rate.Limiter
UserUpdateSubAPIRate *rate.Limiter
UserDeleteAPIRate *rate.Limiter
UserDeleteSubAPIRate *rate.Limiter
UserQuerySubMembersRate *rate.Limiter
UserQueryAPIRate *rate.Limiter
GetSpotLeverageTokenOrderRecordsRate *rate.Limiter
SpotLeverageTokenPurchaseRate *rate.Limiter
SpotLeverTokenRedeemRate *rate.Limiter
GetSpotCrossMarginTradeLoanInfoRate *rate.Limiter
GetSpotCrossMarginTradeAccountRate *rate.Limiter
GetSpotCrossMarginTradeOrdersRate *rate.Limiter
GetSpotCrossMarginTradeRepayHistoryRate *rate.Limiter
SpotCrossMarginTradeLoanRate *rate.Limiter
SpotCrossMarginTradeRepayRate *rate.Limiter
SpotCrossMarginTradeSwitchRate *rate.Limiter
}
// Limit executes rate limiting functionality for Binance
func (r *RateLimit) Limit(ctx context.Context, f request.EndpointLimit) error {
var limiter *rate.Limiter
var tokens int
switch f {
case defaultEPL:
limiter, tokens = r.SpotRate, 1
case createOrderEPL:
limiter, tokens = r.CreateOrderRate, 10
case createSpotOrderEPL:
limiter, tokens = r.CreateSpotOrderRate, 20
case amendOrderEPL:
limiter, tokens = r.AmendOrderRate, 10
case cancelOrderEPL:
limiter, tokens = r.CancelOrderRate, 10
case cancelSpotEPL:
limiter, tokens = r.CancelSpotRate, 20
case cancelAllEPL:
limiter, tokens = r.CancelAllRate, 1
case cancelAllSpotEPL:
limiter, tokens = r.CancelAllSpotRate, 20
case createBatchOrderEPL:
limiter, tokens = r.CreateBatchOrderRate, 10
case amendBatchOrderEPL:
limiter, tokens = r.AmendBatchOrderRate, 10
case cancelBatchOrderEPL:
limiter, tokens = r.CancelBatchOrderRate, 10
case getOrderEPL:
limiter, tokens = r.GetOrderRate, 10
case getOrderHistoryEPL:
limiter, tokens = r.GetOrderHistoryRate, 10
case getPositionListEPL:
limiter, tokens = r.GetPositionListRate, 10
case getExecutionListEPL:
limiter, tokens = r.GetExecutionListRate, 10
case getPositionClosedPNLEPL:
limiter, tokens = r.GetPositionClosedPNLRate, 10
case postPositionSetLeverageEPL:
limiter, tokens = r.PostPositionSetLeverageRate, 10
case setPositionTPLSModeEPL:
limiter, tokens = r.SetPositionTPLSModeRate, 10
case setPositionRiskLimitEPL:
limiter, tokens = r.SetPositionRiskLimitRate, 10
case stopTradingPositionEPL:
limiter, tokens = r.StopTradingPositionRate, 10
case getAccountWalletBalanceEPL:
limiter, tokens = r.GetAccountWalletBalanceRate, 10
case getAccountFeeEPL:
limiter, tokens = r.GetAccountFeeRate, 10
case getAssetTransferQueryInfoEPL:
limiter, tokens = r.GetAssetTransferQueryInfoRate, 1
case getAssetTransferQueryTransferCoinListEPL:
limiter, tokens = r.GetAssetTransferQueryTransferCoinListRate, 1
case getAssetTransferCoinListEPL:
limiter, tokens = r.GetAssetTransferCoinListRate, 1
case getAssetInterTransferListEPL:
limiter, tokens = r.GetAssetInterTransferListRate, 1
case getSubMemberListEPL:
limiter, tokens = r.GetSubMemberListRate, 1
case getAssetUniversalTransferListEPL:
limiter, tokens = r.GetAssetUniversalTransferListRate, 2
case getAssetAccountCoinBalanceEPL:
limiter, tokens = r.GetAssetAccountCoinBalanceRate, 2
case getAssetDepositRecordsEPL:
limiter, tokens = r.GetAssetDepositRecordsRate, 1
case getAssetDepositSubMemberRecordsEPL:
limiter, tokens = r.GetAssetDepositSubMemberRecordsRate, 1
case getAssetDepositSubMemberAddressEPL:
limiter, tokens = r.GetAssetDepositSubMemberAddressRate, 1
case getWithdrawRecordsEPL:
limiter, tokens = r.GetWithdrawRecordsRate, 1
case getAssetCoinInfoEPL:
limiter, tokens = r.GetAssetCoinInfoRate, 1
case getExchangeOrderRecordEPL:
limiter, tokens = r.GetExchangeOrderRecordRate, 1
case interTransferEPL:
limiter, tokens = r.InterTransferRate, 1
case saveTransferSubMemberEPL:
limiter, tokens = r.SaveTransferSubMemberRate, 1
case universalTransferEPL:
limiter, tokens = r.UniversalTransferRate, 5
case createWithdrawalEPL:
limiter, tokens = r.CreateWithdrawalRate, 1
case cancelWithdrawalEPL:
limiter, tokens = r.CancelWithdrawalRate, 1
case userCreateSubMemberEPL:
limiter, tokens = r.UserCreateSubMemberRate, 5
case userCreateSubAPIKeyEPL:
limiter, tokens = r.UserCreateSubAPIKeyRate, 5
case userFrozenSubMemberEPL:
limiter, tokens = r.UserFrozenSubMemberRate, 5
case userUpdateAPIEPL:
limiter, tokens = r.UserUpdateAPIRate, 5
case userUpdateSubAPIEPL:
limiter, tokens = r.UserUpdateSubAPIRate, 5
case userDeleteAPIEPL:
limiter, tokens = r.UserDeleteAPIRate, 5
case userDeleteSubAPIEPL:
limiter, tokens = r.UserDeleteSubAPIRate, 5
case userQuerySubMembersEPL:
limiter, tokens = r.UserQuerySubMembersRate, 10
case userQueryAPIEPL:
limiter, tokens = r.UserQueryAPIRate, 10
case getSpotLeverageTokenOrderRecordsEPL:
limiter, tokens = r.GetSpotLeverageTokenOrderRecordsRate, 50
case spotLeverageTokenPurchaseEPL:
limiter, tokens = r.SpotLeverageTokenPurchaseRate, 20
case spotLeverTokenRedeemEPL:
limiter, tokens = r.SpotLeverTokenRedeemRate, 20
case getSpotCrossMarginTradeLoanInfoEPL:
limiter, tokens = r.GetSpotCrossMarginTradeLoanInfoRate, 50
case getSpotCrossMarginTradeAccountEPL:
limiter, tokens = r.GetSpotCrossMarginTradeAccountRate, 50
case getSpotCrossMarginTradeOrdersEPL:
limiter, tokens = r.GetSpotCrossMarginTradeOrdersRate, 50
case getSpotCrossMarginTradeRepayHistoryEPL:
limiter, tokens = r.GetSpotCrossMarginTradeRepayHistoryRate, 50
case spotCrossMarginTradeLoanEPL:
limiter, tokens = r.SpotCrossMarginTradeLoanRate, 50
case spotCrossMarginTradeRepayEPL:
limiter, tokens = r.SpotCrossMarginTradeRepayRate, 50
case spotCrossMarginTradeSwitchEPL:
limiter, tokens = r.SpotCrossMarginTradeSwitchRate, 50
default:
limiter, tokens = r.SpotRate, 1
}
var finalDelay time.Duration
var reserves = make([]*rate.Reservation, tokens)
for i := 0; i < tokens; i++ {
// Consume tokens 1 at a time as this avoids needing burst capacity in the limiter,
// which would otherwise allow the rate limit to be exceeded over short periods
reserves[i] = limiter.Reserve()
finalDelay = limiter.Reserve().Delay()
}
if dl, ok := ctx.Deadline(); ok && dl.Before(time.Now().Add(finalDelay)) {
// Cancel all potential reservations to free up rate limiter if deadline
// is exceeded.
for x := range reserves {
reserves[x].Cancel()
}
return fmt.Errorf("rate limit delay of %s will exceed deadline: %w",
finalDelay,
context.DeadlineExceeded)
}
time.Sleep(finalDelay)
return nil
}
// SetRateLimit returns the rate limit for the exchange
func SetRateLimit() *RateLimit {
return &RateLimit{
SpotRate: request.NewRateLimit(spotInterval, 120),
CreateOrderRate: request.NewRateLimit(time.Second, 10),
CreateSpotOrderRate: request.NewRateLimit(time.Second, 20),
AmendOrderRate: request.NewRateLimit(time.Second, 10),
CancelOrderRate: request.NewRateLimit(time.Second, 10),
CancelSpotRate: request.NewRateLimit(time.Second, 20),
CancelAllRate: request.NewRateLimit(time.Second, 1),
CancelAllSpotRate: request.NewRateLimit(time.Second, 20),
CreateBatchOrderRate: request.NewRateLimit(time.Second, 10),
AmendBatchOrderRate: request.NewRateLimit(time.Second, 10),
CancelBatchOrderRate: request.NewRateLimit(time.Second, 10),
GetOrderRate: request.NewRateLimit(time.Second, 10),
GetOrderHistoryRate: request.NewRateLimit(time.Second, 10),
GetPositionListRate: request.NewRateLimit(time.Second, 10),
GetExecutionListRate: request.NewRateLimit(time.Second, 10),
GetPositionClosedPNLRate: request.NewRateLimit(time.Second, 10),
PostPositionSetLeverageRate: request.NewRateLimit(time.Second, 10),
SetPositionTPLSModeRate: request.NewRateLimit(time.Second, 10),
SetPositionRiskLimitRate: request.NewRateLimit(time.Second, 10),
StopTradingPositionRate: request.NewRateLimit(time.Second, 10),
GetAccountWalletBalanceRate: request.NewRateLimit(time.Second, 10),
GetAccountFeeRate: request.NewRateLimit(time.Second, 10),
GetAssetTransferQueryInfoRate: request.NewRateLimit(time.Minute, 60),
GetAssetTransferQueryTransferCoinListRate: request.NewRateLimit(time.Minute, 60),
GetAssetTransferCoinListRate: request.NewRateLimit(time.Minute, 60),
GetAssetInterTransferListRate: request.NewRateLimit(time.Minute, 60),
GetSubMemberListRate: request.NewRateLimit(time.Minute, 60),
GetAssetUniversalTransferListRate: request.NewRateLimit(time.Second, 2),
GetAssetAccountCoinBalanceRate: request.NewRateLimit(time.Second, 2),
GetAssetDepositRecordsRate: request.NewRateLimit(time.Minute, 300),
GetAssetDepositSubMemberRecordsRate: request.NewRateLimit(time.Minute, 300),
GetAssetDepositSubMemberAddressRate: request.NewRateLimit(time.Minute, 300),
GetWithdrawRecordsRate: request.NewRateLimit(time.Minute, 300),
GetAssetCoinInfoRate: request.NewRateLimit(time.Minute, 300),
GetExchangeOrderRecordRate: request.NewRateLimit(time.Minute, 300),
InterTransferRate: request.NewRateLimit(time.Minute, 20),
SaveTransferSubMemberRate: request.NewRateLimit(time.Minute, 20),
UniversalTransferRate: request.NewRateLimit(time.Second, 5),
CreateWithdrawalRate: request.NewRateLimit(time.Second, 1),
CancelWithdrawalRate: request.NewRateLimit(time.Minute, 60),
UserCreateSubMemberRate: request.NewRateLimit(time.Second, 5),
UserCreateSubAPIKeyRate: request.NewRateLimit(time.Second, 5),
UserFrozenSubMemberRate: request.NewRateLimit(time.Second, 5),
UserUpdateAPIRate: request.NewRateLimit(time.Second, 5),
UserUpdateSubAPIRate: request.NewRateLimit(time.Second, 5),
UserDeleteAPIRate: request.NewRateLimit(time.Second, 5),
UserDeleteSubAPIRate: request.NewRateLimit(time.Second, 5),
UserQuerySubMembersRate: request.NewRateLimit(time.Second, 10),
UserQueryAPIRate: request.NewRateLimit(time.Second, 10),
GetSpotLeverageTokenOrderRecordsRate: request.NewRateLimit(time.Second, 50),
SpotLeverageTokenPurchaseRate: request.NewRateLimit(time.Second, 20),
SpotLeverTokenRedeemRate: request.NewRateLimit(time.Second, 20),
GetSpotCrossMarginTradeLoanInfoRate: request.NewRateLimit(time.Second, 50),
GetSpotCrossMarginTradeAccountRate: request.NewRateLimit(time.Second, 50),
GetSpotCrossMarginTradeOrdersRate: request.NewRateLimit(time.Second, 50),
GetSpotCrossMarginTradeRepayHistoryRate: request.NewRateLimit(time.Second, 50),
SpotCrossMarginTradeLoanRate: request.NewRateLimit(time.Second, 20),
SpotCrossMarginTradeRepayRate: request.NewRateLimit(time.Second, 20),
SpotCrossMarginTradeSwitchRate: request.NewRateLimit(time.Second, 20),
// GetRateLimit returns the rate limit for the exchange
func GetRateLimit() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
defaultEPL: request.NewRateLimitWithWeight(time.Second*5 /* See: https://bybit-exchange.github.io/docs/v5/rate-limit */, 600, 1),
createOrderEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
createSpotOrderEPL: request.NewRateLimitWithWeight(time.Second, 20, 20),
amendOrderEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
cancelOrderEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
cancelSpotEPL: request.NewRateLimitWithWeight(time.Second, 20, 20),
cancelAllEPL: request.NewRateLimitWithWeight(time.Second, 1, 1),
cancelAllSpotEPL: request.NewRateLimitWithWeight(time.Second, 20, 20),
createBatchOrderEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
amendBatchOrderEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
cancelBatchOrderEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
getOrderEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
getOrderHistoryEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
getPositionListEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
getExecutionListEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
getPositionClosedPNLEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
postPositionSetLeverageEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
setPositionTPLSModeEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
setPositionRiskLimitEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
stopTradingPositionEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
getAccountWalletBalanceEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
getAccountFeeEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
getAssetTransferQueryInfoEPL: request.NewRateLimitWithWeight(time.Minute, 60, 1),
getAssetTransferQueryTransferCoinListEPL: request.NewRateLimitWithWeight(time.Minute, 60, 1),
getAssetTransferCoinListEPL: request.NewRateLimitWithWeight(time.Minute, 60, 1),
getAssetInterTransferListEPL: request.NewRateLimitWithWeight(time.Minute, 60, 1),
getSubMemberListEPL: request.NewRateLimitWithWeight(time.Minute, 60, 1),
getAssetUniversalTransferListEPL: request.NewRateLimitWithWeight(time.Second, 2, 2),
getAssetAccountCoinBalanceEPL: request.NewRateLimitWithWeight(time.Second, 2, 2),
getAssetDepositRecordsEPL: request.NewRateLimitWithWeight(time.Minute, 30, 1),
getAssetDepositSubMemberRecordsEPL: request.NewRateLimitWithWeight(time.Minute, 30, 1),
getAssetDepositSubMemberAddressEPL: request.NewRateLimitWithWeight(time.Minute, 30, 1),
getWithdrawRecordsEPL: request.NewRateLimitWithWeight(time.Minute, 30, 1),
getAssetCoinInfoEPL: request.NewRateLimitWithWeight(time.Minute, 30, 1),
getExchangeOrderRecordEPL: request.NewRateLimitWithWeight(time.Minute, 30, 1),
interTransferEPL: request.NewRateLimitWithWeight(time.Minute, 20, 1),
saveTransferSubMemberEPL: request.NewRateLimitWithWeight(time.Minute, 20, 1),
universalTransferEPL: request.NewRateLimitWithWeight(time.Second, 5, 5),
createWithdrawalEPL: request.NewRateLimitWithWeight(time.Second, 1, 1),
cancelWithdrawalEPL: request.NewRateLimitWithWeight(time.Minute, 60, 1),
userCreateSubMemberEPL: request.NewRateLimitWithWeight(time.Second, 5, 5),
userCreateSubAPIKeyEPL: request.NewRateLimitWithWeight(time.Second, 5, 5),
userFrozenSubMemberEPL: request.NewRateLimitWithWeight(time.Second, 5, 5),
userUpdateAPIEPL: request.NewRateLimitWithWeight(time.Second, 5, 5),
userUpdateSubAPIEPL: request.NewRateLimitWithWeight(time.Second, 5, 5),
userDeleteAPIEPL: request.NewRateLimitWithWeight(time.Second, 5, 5),
userDeleteSubAPIEPL: request.NewRateLimitWithWeight(time.Second, 5, 5),
userQuerySubMembersEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
userQueryAPIEPL: request.NewRateLimitWithWeight(time.Second, 10, 10),
getSpotLeverageTokenOrderRecordsEPL: request.NewRateLimitWithWeight(time.Second, 50, 50),
spotLeverageTokenPurchaseEPL: request.NewRateLimitWithWeight(time.Second, 20, 20),
spotLeverTokenRedeemEPL: request.NewRateLimitWithWeight(time.Second, 20, 20),
getSpotCrossMarginTradeLoanInfoEPL: request.NewRateLimitWithWeight(time.Second, 50, 50),
getSpotCrossMarginTradeAccountEPL: request.NewRateLimitWithWeight(time.Second, 50, 50),
getSpotCrossMarginTradeOrdersEPL: request.NewRateLimitWithWeight(time.Second, 50, 50),
getSpotCrossMarginTradeRepayHistoryEPL: request.NewRateLimitWithWeight(time.Second, 50, 50),
spotCrossMarginTradeLoanEPL: request.NewRateLimitWithWeight(time.Second, 20, 50),
spotCrossMarginTradeRepayEPL: request.NewRateLimitWithWeight(time.Second, 20, 50),
spotCrossMarginTradeSwitchEPL: request.NewRateLimitWithWeight(time.Second, 20, 50),
}
}

View File

@@ -767,7 +767,7 @@ func (c *CoinbasePro) SendHTTPRequest(ctx context.Context, ep exchange.URL, path
HTTPRecording: c.HTTPRecording,
}
return c.SendPayload(ctx, request.Unset, func() (*request.Item, error) {
return c.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) {
return item, nil
}, request.UnauthenticatedRequest)
}

View File

@@ -109,7 +109,7 @@ func (c *CoinbasePro) SetDefaults() {
c.Requester, err = request.New(c.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
request.WithLimiter(GetRateLimit()))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -1,11 +1,9 @@
package coinbasepro
import (
"context"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
// Coinbasepro rate limit conts
@@ -15,24 +13,10 @@ const (
coinbaseproUnauthRate = 2
)
// RateLimit implements the request.Limiter interface
type RateLimit struct {
Auth *rate.Limiter
UnAuth *rate.Limiter
}
// Limit limits outbound calls
func (r *RateLimit) Limit(ctx context.Context, f request.EndpointLimit) error {
if f == request.Auth {
return r.Auth.Wait(ctx)
}
return r.UnAuth.Wait(ctx)
}
// SetRateLimit returns the rate limit for the exchange
func SetRateLimit() *RateLimit {
return &RateLimit{
Auth: request.NewRateLimit(coinbaseproRateInterval, coinbaseproAuthRate),
UnAuth: request.NewRateLimit(coinbaseproRateInterval, coinbaseproUnauthRate),
// GetRateLimit returns the rate limit for the exchange
func GetRateLimit() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
request.Auth: request.NewRateLimitWithWeight(coinbaseproRateInterval, coinbaseproAuthRate, 1),
request.UnAuth: request.NewRateLimitWithWeight(coinbaseproRateInterval, coinbaseproUnauthRate, 1),
}
}

View File

@@ -152,7 +152,7 @@ func (d *Deribit) SetDefaults() {
}
d.Requester, err = request.New(d.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()),
request.WithLimiter(GetRateLimits()),
)
if err != nil {
log.Errorln(log.ExchangeSys, err)

View File

@@ -1,79 +1,32 @@
package deribit
import (
"context"
"fmt"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
const (
// request rates per interval
// Request rates per interval
minMatchingBurst = 100
nonMatchingRate = 20
minMatchingRate = 5
portfoliMarginRate = 1
// Weightings
matchingWeight = 5
standardWeight = 1
// Rate limit keys
nonMatchingEPL request.EndpointLimit = iota
matchingEPL
portfolioMarginEPL
privatePortfolioMarginEPL
)
// RateLimiter holds the rate limiter to endpoints
type RateLimiter struct {
NonMatchingEngine *rate.Limiter
MatchingEngine *rate.Limiter
PortfolioMargin *rate.Limiter
PrivatePortfolioMargin *rate.Limiter
}
// SetRateLimit returns the rate limit for the exchange
func SetRateLimit() *RateLimiter {
return &RateLimiter{
NonMatchingEngine: request.NewRateLimit(time.Second, nonMatchingRate),
MatchingEngine: request.NewRateLimit(time.Second, minMatchingBurst),
PortfolioMargin: request.NewRateLimit(5*time.Second, portfoliMarginRate),
PrivatePortfolioMargin: request.NewRateLimit(5*time.Second, portfoliMarginRate),
// GetRateLimits returns the rate limit for the exchange
func GetRateLimits() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
nonMatchingEPL: request.GetRateLimiterWithWeight(request.NewRateLimit(time.Second, nonMatchingRate), standardWeight),
matchingEPL: request.GetRateLimiterWithWeight(request.NewRateLimit(time.Second, minMatchingBurst), matchingWeight),
portfolioMarginEPL: request.GetRateLimiterWithWeight(request.NewRateLimit(5*time.Second, portfoliMarginRate), standardWeight),
privatePortfolioMarginEPL: request.GetRateLimiterWithWeight(request.NewRateLimit(5*time.Second, portfoliMarginRate), standardWeight),
}
}
// Limit executes rate limiting functionality for Binance
func (r *RateLimiter) Limit(ctx context.Context, f request.EndpointLimit) error {
var limiter *rate.Limiter
var tokens int
switch f {
case nonMatchingEPL:
limiter, tokens = r.NonMatchingEngine, 1
case portfolioMarginEPL:
limiter, tokens = r.PortfolioMargin, portfoliMarginRate
case privatePortfolioMarginEPL:
limiter, tokens = r.PrivatePortfolioMargin, portfoliMarginRate
default:
limiter, tokens = r.MatchingEngine, minMatchingRate
}
var finalDelay time.Duration
var reserves = make([]*rate.Reservation, tokens)
for i := 0; i < tokens; i++ {
// Consume tokens 1 at a time as this avoids needing burst capacity in the limiter,
// which would otherwise allow the rate limit to be exceeded over short periods
reserves[i] = limiter.Reserve()
finalDelay = reserves[i].Delay()
}
if dl, ok := ctx.Deadline(); ok && dl.Before(time.Now().Add(finalDelay)) {
// Cancel all potential reservations to free up rate limiter if deadline
// is exceeded.
for x := range reserves {
reserves[x].Cancel()
}
return fmt.Errorf("rate limit delay of %s will exceed deadline: %w",
finalDelay,
context.DeadlineExceeded)
}
time.Sleep(finalDelay)
return nil
}

View File

@@ -90,7 +90,7 @@ func (e *EXMO) SetDefaults() {
e.Requester, err = request.New(e.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(request.NewBasicRateLimit(exmoRateInterval, exmoRequestRate)))
request.WithLimiter(request.NewBasicRateLimit(exmoRateInterval, exmoRequestRate, 1)))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -142,7 +142,7 @@ func (g *Gateio) SetDefaults() {
}
g.Requester, err = request.New(g.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()),
request.WithLimiter(GetRateLimit()),
)
if err != nil {
log.Errorln(log.ExchangeSys, err)

View File

@@ -1,12 +1,9 @@
package gateio
import (
"context"
"fmt"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
// GateIO endpoints limits.
@@ -40,79 +37,18 @@ const (
threeSecondsInterval = time.Second * 3
)
// RateLimitter represents a rate limiter structure for gateIO endpoints.
type RateLimitter struct {
SpotDefault *rate.Limiter
SpotPrivate *rate.Limiter
SpotPlaceOrders *rate.Limiter
SpotCancelOrders *rate.Limiter
PerpetualSwapDefault *rate.Limiter
PerpetualSwapPlaceOrders *rate.Limiter
PerpetualSwapPrivate *rate.Limiter
PerpetualSwapCancelOrders *rate.Limiter
Wallet *rate.Limiter
Withdrawal *rate.Limiter
}
// Limit executes rate limiting functionality
// implements the request.Limiter interface
func (r *RateLimitter) Limit(ctx context.Context, epl request.EndpointLimit) error {
var limiter *rate.Limiter
var tokens int
switch epl {
case spotDefaultEPL:
limiter, tokens = r.SpotDefault, 1
case spotPrivateEPL:
return r.SpotPrivate.Wait(ctx)
case spotPlaceOrdersEPL:
return r.SpotPlaceOrders.Wait(ctx)
case spotCancelOrdersEPL:
return r.SpotCancelOrders.Wait(ctx)
case perpetualSwapDefaultEPL:
limiter, tokens = r.PerpetualSwapDefault, 1
case perpetualSwapPlaceOrdersEPL:
return r.PerpetualSwapPlaceOrders.Wait(ctx)
case perpetualSwapPrivateEPL:
return r.PerpetualSwapPrivate.Wait(ctx)
case perpetualSwapCancelOrdersEPL:
return r.PerpetualSwapCancelOrders.Wait(ctx)
case walletEPL:
return r.Wallet.Wait(ctx)
case withdrawalEPL:
return r.Withdrawal.Wait(ctx)
default:
}
var finalDelay time.Duration
var reserves = make([]*rate.Reservation, tokens)
for i := 0; i < tokens; i++ {
reserves[i] = limiter.Reserve()
finalDelay = reserves[i].Delay()
}
if dl, ok := ctx.Deadline(); ok && dl.Before(time.Now().Add(finalDelay)) {
for x := range reserves {
reserves[x].Cancel()
}
return fmt.Errorf("rate limit delay of %s will exceed deadline: %w",
finalDelay,
context.DeadlineExceeded)
}
time.Sleep(finalDelay)
return nil
}
// SetRateLimit returns the rate limiter for the exchange
func SetRateLimit() *RateLimitter {
return &RateLimitter{
SpotDefault: request.NewRateLimit(oneSecondInterval, spotPublicRate),
SpotPrivate: request.NewRateLimit(oneSecondInterval, spotPrivateRate),
SpotPlaceOrders: request.NewRateLimit(oneSecondInterval, spotPlaceOrdersRate),
SpotCancelOrders: request.NewRateLimit(oneSecondInterval, spotCancelOrdersRate),
PerpetualSwapDefault: request.NewRateLimit(oneSecondInterval, perpetualSwapPublicRate),
PerpetualSwapPlaceOrders: request.NewRateLimit(oneSecondInterval, perpetualSwapPlaceOrdersRate),
PerpetualSwapPrivate: request.NewRateLimit(oneSecondInterval, perpetualSwapPrivateRate),
PerpetualSwapCancelOrders: request.NewRateLimit(oneSecondInterval, perpetualSwapCancelOrdersRate),
Wallet: request.NewRateLimit(oneSecondInterval, walletRate),
Withdrawal: request.NewRateLimit(threeSecondsInterval, withdrawalRate),
// GetRateLimit returns the rate limiter for the exchange
func GetRateLimit() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
spotDefaultEPL: request.NewRateLimitWithWeight(oneSecondInterval, spotPublicRate, 1),
spotPrivateEPL: request.NewRateLimitWithWeight(oneSecondInterval, spotPrivateRate, 1),
spotPlaceOrdersEPL: request.NewRateLimitWithWeight(oneSecondInterval, spotPlaceOrdersRate, 1),
spotCancelOrdersEPL: request.NewRateLimitWithWeight(oneSecondInterval, spotCancelOrdersRate, 1),
perpetualSwapDefaultEPL: request.NewRateLimitWithWeight(oneSecondInterval, perpetualSwapPublicRate, 1),
perpetualSwapPlaceOrdersEPL: request.NewRateLimitWithWeight(oneSecondInterval, perpetualSwapPlaceOrdersRate, 1),
perpetualSwapPrivateEPL: request.NewRateLimitWithWeight(oneSecondInterval, perpetualSwapPrivateRate, 1),
perpetualSwapCancelOrdersEPL: request.NewRateLimitWithWeight(oneSecondInterval, perpetualSwapCancelOrdersRate, 1),
walletEPL: request.NewRateLimitWithWeight(oneSecondInterval, walletRate, 1),
withdrawalEPL: request.NewRateLimitWithWeight(threeSecondsInterval, withdrawalRate, 1),
}
}

View File

@@ -402,7 +402,7 @@ func (g *Gemini) SendHTTPRequest(ctx context.Context, ep exchange.URL, path stri
HTTPRecording: g.HTTPRecording,
}
return g.SendPayload(ctx, request.Unset, func() (*request.Item, error) {
return g.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) {
return item, nil
}, request.UnauthenticatedRequest)
}

View File

@@ -93,7 +93,7 @@ func (g *Gemini) SetDefaults() {
g.Requester, err = request.New(g.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
request.WithLimiter(GetRateLimit()))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -1,11 +1,9 @@
package gemini
import (
"context"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
const (
@@ -15,24 +13,10 @@ const (
geminiUnauthRate = 120
)
// RateLimit implements the request.Limiter interface
type RateLimit struct {
Auth *rate.Limiter
UnAuth *rate.Limiter
}
// Limit limits the endpoint functionality
func (r *RateLimit) Limit(ctx context.Context, f request.EndpointLimit) error {
if f == request.Auth {
return r.Auth.Wait(ctx)
}
return r.UnAuth.Wait(ctx)
}
// SetRateLimit returns the rate limit for the exchange
func SetRateLimit() *RateLimit {
return &RateLimit{
Auth: request.NewRateLimit(geminiRateInterval, geminiAuthRate),
UnAuth: request.NewRateLimit(geminiRateInterval, geminiUnauthRate),
// GetRateLimit returns the rate limit for the exchange
func GetRateLimit() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
request.Auth: request.NewRateLimitWithWeight(geminiRateInterval, geminiAuthRate, 1),
request.UnAuth: request.NewRateLimitWithWeight(geminiRateInterval, geminiUnauthRate, 1),
}
}

View File

@@ -112,7 +112,7 @@ func (h *HitBTC) SetDefaults() {
h.Requester, err = request.New(h.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
request.WithLimiter(GetRateLimit()))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -1,12 +1,9 @@
package hitbtc
import (
"context"
"errors"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
const (
@@ -20,32 +17,11 @@ const (
otherRequests
)
// RateLimit implements the request.Limiter interface
type RateLimit struct {
MarketData *rate.Limiter
Trading *rate.Limiter
Other *rate.Limiter
}
// Limit limits outbound requests
func (r *RateLimit) Limit(ctx context.Context, f request.EndpointLimit) error {
switch f {
case marketRequests:
return r.MarketData.Wait(ctx)
case tradingRequests:
return r.Trading.Wait(ctx)
case otherRequests:
return r.Other.Wait(ctx)
default:
return errors.New("functionality not found")
}
}
// SetRateLimit returns the rate limit for the exchange
func SetRateLimit() *RateLimit {
return &RateLimit{
MarketData: request.NewRateLimit(hitbtcRateInterval, hitbtcMarketDataReqRate),
Trading: request.NewRateLimit(hitbtcRateInterval, hitbtcTradingReqRate),
Other: request.NewRateLimit(hitbtcRateInterval, hitbtcAllOthers),
// GetRateLimit returns the rate limit for the exchange
func GetRateLimit() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
marketRequests: request.NewRateLimitWithWeight(hitbtcRateInterval, hitbtcMarketDataReqRate, 1),
tradingRequests: request.NewRateLimitWithWeight(hitbtcRateInterval, hitbtcTradingReqRate, 1),
otherRequests: request.NewRateLimitWithWeight(hitbtcRateInterval, hitbtcAllOthers, 1),
}
}

View File

@@ -165,7 +165,7 @@ func (h *HUOBI) SetDefaults() {
h.Requester, err = request.New(h.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
request.WithLimiter(GetRateLimit()))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -1,11 +1,9 @@
package huobi
import (
"context"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
const (
@@ -28,47 +26,17 @@ const (
huobiFuturesUnAuth
huobiFuturesTransfer
huobiSwapAuth
huobiSwapUnauth
huobiSwapUnAuth
)
// RateLimit implements the request.Limiter interface
type RateLimit struct {
Spot *rate.Limiter
FuturesAuth *rate.Limiter
FuturesUnauth *rate.Limiter
SwapAuth *rate.Limiter
SwapUnauth *rate.Limiter
FuturesXfer *rate.Limiter
}
// Limit limits outbound requests
func (r *RateLimit) Limit(ctx context.Context, f request.EndpointLimit) error {
switch f {
// TODO: Add futures and swap functionality
case huobiFuturesAuth:
return r.FuturesAuth.Wait(ctx)
case huobiFuturesUnAuth:
return r.FuturesUnauth.Wait(ctx)
case huobiFuturesTransfer:
return r.FuturesXfer.Wait(ctx)
case huobiSwapAuth:
return r.SwapAuth.Wait(ctx)
case huobiSwapUnauth:
return r.SwapUnauth.Wait(ctx)
default:
// Spot calls
return r.Spot.Wait(ctx)
}
}
// SetRateLimit returns the rate limit for the exchange
func SetRateLimit() *RateLimit {
return &RateLimit{
Spot: request.NewRateLimit(huobiSpotRateInterval, huobiSpotRequestRate),
FuturesAuth: request.NewRateLimit(huobiFuturesRateInterval, huobiFuturesAuthRequestRate),
FuturesUnauth: request.NewRateLimit(huobiFuturesRateInterval, huobiFuturesUnAuthRequestRate),
SwapAuth: request.NewRateLimit(huobiSwapRateInterval, huobiSwapAuthRequestRate),
SwapUnauth: request.NewRateLimit(huobiSwapRateInterval, huobiSwapUnauthRequestRate),
FuturesXfer: request.NewRateLimit(huobiFuturesTransferRateInterval, huobiFuturesTransferReqRate),
// GetRateLimit returns the rate limit for the exchange
func GetRateLimit() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
request.Unset: request.NewRateLimitWithWeight(huobiSpotRateInterval, huobiSpotRequestRate, 1),
huobiFuturesAuth: request.NewRateLimitWithWeight(huobiFuturesRateInterval, huobiFuturesAuthRequestRate, 1),
huobiFuturesUnAuth: request.NewRateLimitWithWeight(huobiFuturesRateInterval, huobiFuturesUnAuthRequestRate, 1),
huobiSwapAuth: request.NewRateLimitWithWeight(huobiSwapRateInterval, huobiSwapAuthRequestRate, 1),
huobiSwapUnAuth: request.NewRateLimitWithWeight(huobiSwapRateInterval, huobiSwapUnauthRequestRate, 1),
huobiFuturesTransfer: request.NewRateLimitWithWeight(huobiFuturesTransferRateInterval, huobiFuturesTransferReqRate, 1),
}
}

View File

@@ -172,7 +172,7 @@ func (k *Kraken) SetDefaults() {
k.Requester, err = request.New(k.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(request.NewBasicRateLimit(krakenRateInterval, krakenRequestRate)))
request.WithLimiter(request.NewBasicRateLimit(krakenRateInterval, krakenRequestRate, 1)))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -1,13 +1,9 @@
package kucoin
import (
"context"
"errors"
"fmt"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
const (
@@ -15,39 +11,6 @@ const (
oneMinuteInterval = time.Minute
)
// RateLimit implements the request.Limiter interface
type RateLimit struct {
RetrieveAccountLedger *rate.Limiter
MasterSubUserTransfer *rate.Limiter
RetrieveDepositList *rate.Limiter
RetrieveV1HistoricalDepositList *rate.Limiter
RetrieveWithdrawalList *rate.Limiter
RetrieveV1HistoricalWithdrawalList *rate.Limiter
PlaceOrder *rate.Limiter
PlaceMarginOrders *rate.Limiter
PlaceBulkOrders *rate.Limiter
CancelOrder *rate.Limiter
CancelAllOrders *rate.Limiter
ListOrders *rate.Limiter
ListFills *rate.Limiter
RetrieveFullOrderbook *rate.Limiter
RetrieveMarginAccount *rate.Limiter
SpotRate *rate.Limiter
FuturesRate *rate.Limiter
FRetrieveAccountOverviewRate *rate.Limiter
FRetrieveTransactionHistoryRate *rate.Limiter
FPlaceOrderRate *rate.Limiter
FCancelAnOrderRate *rate.Limiter
FLimitOrderMassCancelationRate *rate.Limiter
FRetrieveOrderListRate *rate.Limiter
FRetrieveFillsRate *rate.Limiter
FRecentFillsRate *rate.Limiter
FRetrievePositionListRate *rate.Limiter
FRetrieveFundingHistoryRate *rate.Limiter
FRetrieveFullOrderbookLevel2Rate *rate.Limiter
}
// rate of request per interval
const (
retrieveAccountLedgerRate = 18
@@ -116,129 +79,41 @@ const (
defaultFuturesEPL
)
// Limit executes rate limiting functionality for Kucoin
func (r *RateLimit) Limit(ctx context.Context, epl request.EndpointLimit) error {
var limiter *rate.Limiter
var tokens int
switch epl {
case retrieveAccountLedgerEPL:
return r.RetrieveAccountLedger.Wait(ctx)
case masterSubUserTransferEPL:
return r.MasterSubUserTransfer.Wait(ctx)
case retrieveDepositListEPL:
return r.RetrieveDepositList.Wait(ctx)
case retrieveV1HistoricalDepositListEPL:
return r.RetrieveV1HistoricalDepositList.Wait(ctx)
case retrieveWithdrawalListEPL:
return r.RetrieveWithdrawalList.Wait(ctx)
case retrieveV1HistoricalWithdrawalListEPL:
return r.RetrieveV1HistoricalWithdrawalList.Wait(ctx)
case placeOrderEPL:
return r.PlaceOrder.Wait(ctx)
case placeMarginOrdersEPL:
return r.PlaceMarginOrders.Wait(ctx)
case placeBulkOrdersEPL:
return r.PlaceBulkOrders.Wait(ctx)
case cancelOrderEPL:
return r.CancelOrder.Wait(ctx)
case cancelAllOrdersEPL:
return r.CancelAllOrders.Wait(ctx)
case listOrdersEPL:
return r.ListOrders.Wait(ctx)
case listFillsEPL:
return r.ListFills.Wait(ctx)
case retrieveFullOrderbookEPL:
return r.RetrieveFullOrderbook.Wait(ctx)
case retrieveMarginAccountEPL:
return r.RetrieveMarginAccount.Wait(ctx)
case futuresRetrieveAccountOverviewEPL:
return r.FRetrieveAccountOverviewRate.Wait(ctx)
case futuresRetrieveTransactionHistoryEPL:
return r.FRetrieveTransactionHistoryRate.Wait(ctx)
case futuresPlaceOrderEPL:
return r.FPlaceOrderRate.Wait(ctx)
case futuresCancelAnOrderEPL:
return r.FCancelAnOrderRate.Wait(ctx)
case futuresLimitOrderMassCancelationEPL:
return r.FLimitOrderMassCancelationRate.Wait(ctx)
case futuresRetrieveOrderListEPL:
return r.FRetrieveOrderListRate.Wait(ctx)
case futuresRetrieveFillsEPL:
return r.FRetrieveFillsRate.Wait(ctx)
case futuresRecentFillsEPL:
return r.FRecentFillsRate.Wait(ctx)
case futuresRetrievePositionListEPL:
return r.FRetrievePositionListRate.Wait(ctx)
case futuresRetrieveFundingHistoryEPL:
return r.FRetrieveFundingHistoryRate.Wait(ctx)
case futuresRetrieveFullOrderbookLevel2EPL:
return r.FRetrieveFullOrderbookLevel2Rate.Wait(ctx)
case defaultSpotEPL:
limiter, tokens = r.SpotRate, 1
case defaultFuturesEPL:
limiter, tokens = r.FuturesRate, 1
default:
return errors.New("endpoint rate limit functionality not found")
}
var finalDelay time.Duration
var reserves = make([]*rate.Reservation, tokens)
for i := 0; i < tokens; i++ {
// Consume tokens 1 at a time as this avoids needing burst capacity in the limiter,
// which would otherwise allow the rate limit to be exceeded over short periods
reserves[i] = limiter.Reserve()
finalDelay = reserves[i].Delay()
}
if dl, ok := ctx.Deadline(); ok && dl.Before(time.Now().Add(finalDelay)) {
// Cancel all potential reservations to free up rate limiter if deadline
// is exceeded.
for x := range reserves {
reserves[x].Cancel()
}
return fmt.Errorf("rate limit delay of %s will exceed deadline: %w",
finalDelay,
context.DeadlineExceeded)
}
time.Sleep(finalDelay)
return nil
}
// SetRateLimit returns a RateLimit instance, which implements the request.Limiter interface.
func SetRateLimit() *RateLimit {
return &RateLimit{
// GetRateLimit returns a RateLimit instance, which implements the request.Limiter interface.
func GetRateLimit() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
// spot specific rate limiters
RetrieveAccountLedger: request.NewRateLimit(threeSecondsInterval, retrieveAccountLedgerRate),
MasterSubUserTransfer: request.NewRateLimit(threeSecondsInterval, masterSubUserTransferRate),
RetrieveDepositList: request.NewRateLimit(threeSecondsInterval, retrieveDepositListRate),
RetrieveV1HistoricalDepositList: request.NewRateLimit(threeSecondsInterval, retrieveV1HistoricalDepositListRate),
RetrieveWithdrawalList: request.NewRateLimit(threeSecondsInterval, retrieveWithdrawalListRate),
RetrieveV1HistoricalWithdrawalList: request.NewRateLimit(threeSecondsInterval, retrieveV1HistoricalWithdrawalListRate),
PlaceOrder: request.NewRateLimit(threeSecondsInterval, placeOrderRate),
PlaceMarginOrders: request.NewRateLimit(threeSecondsInterval, placeMarginOrdersRate),
PlaceBulkOrders: request.NewRateLimit(threeSecondsInterval, placeBulkOrdersRate),
CancelOrder: request.NewRateLimit(threeSecondsInterval, cancelOrderRate),
CancelAllOrders: request.NewRateLimit(threeSecondsInterval, cancelAllOrdersRate),
ListOrders: request.NewRateLimit(threeSecondsInterval, listOrdersRate),
ListFills: request.NewRateLimit(threeSecondsInterval, listFillsRate),
RetrieveFullOrderbook: request.NewRateLimit(threeSecondsInterval, retrieveFullOrderbookRate),
RetrieveMarginAccount: request.NewRateLimit(threeSecondsInterval, retrieveMarginAccountRate),
retrieveAccountLedgerEPL: request.NewRateLimitWithWeight(threeSecondsInterval, retrieveAccountLedgerRate, 1),
masterSubUserTransferEPL: request.NewRateLimitWithWeight(threeSecondsInterval, masterSubUserTransferRate, 1),
retrieveDepositListEPL: request.NewRateLimitWithWeight(threeSecondsInterval, retrieveDepositListRate, 1),
retrieveV1HistoricalDepositListEPL: request.NewRateLimitWithWeight(threeSecondsInterval, retrieveV1HistoricalDepositListRate, 1),
retrieveWithdrawalListEPL: request.NewRateLimitWithWeight(threeSecondsInterval, retrieveWithdrawalListRate, 1),
retrieveV1HistoricalWithdrawalListEPL: request.NewRateLimitWithWeight(threeSecondsInterval, retrieveV1HistoricalWithdrawalListRate, 1),
placeOrderEPL: request.NewRateLimitWithWeight(threeSecondsInterval, placeOrderRate, 1),
placeMarginOrdersEPL: request.NewRateLimitWithWeight(threeSecondsInterval, placeMarginOrdersRate, 1),
placeBulkOrdersEPL: request.NewRateLimitWithWeight(threeSecondsInterval, placeBulkOrdersRate, 1),
cancelOrderEPL: request.NewRateLimitWithWeight(threeSecondsInterval, cancelOrderRate, 1),
cancelAllOrdersEPL: request.NewRateLimitWithWeight(threeSecondsInterval, cancelAllOrdersRate, 1),
listOrdersEPL: request.NewRateLimitWithWeight(threeSecondsInterval, listOrdersRate, 1),
listFillsEPL: request.NewRateLimitWithWeight(threeSecondsInterval, listFillsRate, 1),
retrieveFullOrderbookEPL: request.NewRateLimitWithWeight(threeSecondsInterval, retrieveFullOrderbookRate, 1),
retrieveMarginAccountEPL: request.NewRateLimitWithWeight(threeSecondsInterval, retrieveMarginAccountRate, 1),
// default spot and futures rates
SpotRate: request.NewRateLimit(oneMinuteInterval, defaultSpotRate),
FuturesRate: request.NewRateLimit(oneMinuteInterval, defaultFuturesRate),
defaultSpotEPL: request.NewRateLimitWithWeight(oneMinuteInterval, defaultSpotRate, 1),
defaultFuturesEPL: request.NewRateLimitWithWeight(oneMinuteInterval, defaultFuturesRate, 1),
// futures specific rate limiters
FRetrieveAccountOverviewRate: request.NewRateLimit(threeSecondsInterval, futuresRetrieveAccountOverviewRate),
FRetrieveTransactionHistoryRate: request.NewRateLimit(threeSecondsInterval, futuresRetrieveTransactionHistoryRate),
FPlaceOrderRate: request.NewRateLimit(threeSecondsInterval, futuresPlaceOrderRate),
FCancelAnOrderRate: request.NewRateLimit(threeSecondsInterval, futuresCancelAnOrderRate),
FLimitOrderMassCancelationRate: request.NewRateLimit(threeSecondsInterval, futuresLimitOrderMassCancelationRate),
FRetrieveOrderListRate: request.NewRateLimit(threeSecondsInterval, futuresRetrieveOrderListRate),
FRetrieveFillsRate: request.NewRateLimit(threeSecondsInterval, futuresRetrieveFillsRate),
FRecentFillsRate: request.NewRateLimit(threeSecondsInterval, futuresRecentFillsRate),
FRetrievePositionListRate: request.NewRateLimit(threeSecondsInterval, futuresRetrievePositionListRate),
FRetrieveFundingHistoryRate: request.NewRateLimit(threeSecondsInterval, futuresRetrieveFundingHistoryRate),
FRetrieveFullOrderbookLevel2Rate: request.NewRateLimit(threeSecondsInterval, futuresRetrieveFullOrderbookLevel2Rate),
futuresRetrieveAccountOverviewEPL: request.NewRateLimitWithWeight(threeSecondsInterval, futuresRetrieveAccountOverviewRate, 1),
futuresRetrieveTransactionHistoryEPL: request.NewRateLimitWithWeight(threeSecondsInterval, futuresRetrieveTransactionHistoryRate, 1),
futuresPlaceOrderEPL: request.NewRateLimitWithWeight(threeSecondsInterval, futuresPlaceOrderRate, 1),
futuresCancelAnOrderEPL: request.NewRateLimitWithWeight(threeSecondsInterval, futuresCancelAnOrderRate, 1),
futuresLimitOrderMassCancelationEPL: request.NewRateLimitWithWeight(threeSecondsInterval, futuresLimitOrderMassCancelationRate, 1),
futuresRetrieveOrderListEPL: request.NewRateLimitWithWeight(threeSecondsInterval, futuresRetrieveOrderListRate, 1),
futuresRetrieveFillsEPL: request.NewRateLimitWithWeight(threeSecondsInterval, futuresRetrieveFillsRate, 1),
futuresRecentFillsEPL: request.NewRateLimitWithWeight(threeSecondsInterval, futuresRecentFillsRate, 1),
futuresRetrievePositionListEPL: request.NewRateLimitWithWeight(threeSecondsInterval, futuresRetrievePositionListRate, 1),
futuresRetrieveFundingHistoryEPL: request.NewRateLimitWithWeight(threeSecondsInterval, futuresRetrieveFundingHistoryRate, 1),
futuresRetrieveFullOrderbookLevel2EPL: request.NewRateLimitWithWeight(threeSecondsInterval, futuresRetrieveFullOrderbookLevel2Rate, 1),
}
}

View File

@@ -159,7 +159,7 @@ func (ku *Kucoin) SetDefaults() {
}
ku.Requester, err = request.New(ku.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
request.WithLimiter(GetRateLimit()))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -1,12 +1,9 @@
package okcoin
import (
"context"
"errors"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
// Interval instances
@@ -16,79 +13,6 @@ const (
fiveSecondsInterval = time.Second * 5
)
// RateLimit implementa a rate Limiter
type RateLimit struct {
PlaceTradeOrder *rate.Limiter
PlaceTradeMultipleOrders *rate.Limiter
CancelTradeOrder *rate.Limiter
CancelMultipleOrder *rate.Limiter
AmendTradeOrder *rate.Limiter
AmendMultipleOrders *rate.Limiter
GetOrderDetails *rate.Limiter
GetOrderList *rate.Limiter
GetOrderHistory *rate.Limiter
GetOrderhistory3Months *rate.Limiter
GetTransactionDetails3Days *rate.Limiter
GetTransactionDetails3Months *rate.Limiter
PlaceAlgoOrder *rate.Limiter
CancelAlgoOrder *rate.Limiter
CancelAdvancedAlgoOrder *rate.Limiter
GetAlgoOrderList *rate.Limiter
GetAlgoOrderHistory *rate.Limiter
GetFundingCurrencies *rate.Limiter
GetFundingAccountBalance *rate.Limiter
GetAccountAssetValuation *rate.Limiter
FundingTransfer *rate.Limiter
GetFundsTransferState *rate.Limiter
AssetBillsDetail *rate.Limiter
LightningDeposits *rate.Limiter
GetAssetDepositAddress *rate.Limiter
GetDepositHistory *rate.Limiter
PostWithdrawal *rate.Limiter
PostLightningWithdrawal *rate.Limiter
CancelWithdrawal *rate.Limiter
GetAssetWithdrawalHistory *rate.Limiter
GetAccountBalance *rate.Limiter
GetBillsDetailLast3Month *rate.Limiter
GetBillsDetail *rate.Limiter
GetAccountConfiguration *rate.Limiter
GetMaxBuySellAmountOpenAmount *rate.Limiter
GetMaxAvailableTradableAmount *rate.Limiter
GetFeeRates *rate.Limiter
GetMaxWithdrawals *rate.Limiter
GetAvailablePairs *rate.Limiter
RequestQuotes *rate.Limiter
PlaceRFQOrder *rate.Limiter
GetRFQTradeOrderDetails *rate.Limiter
GetRFQTradeOrderHistory *rate.Limiter
FiatDepositRate *rate.Limiter
FiatCancelDepositRate *rate.Limiter
FiatDepositHistoryRate *rate.Limiter
FiatWithdrawalRate *rate.Limiter
FiatCancelWithdrawalRate *rate.Limiter
FiatGetWithdrawalsRate *rate.Limiter
FiatGetChannelInfoRate *rate.Limiter
SubAccountsList *rate.Limiter
GetAPIKeyOfASubAccount *rate.Limiter
GetSubAccountTradingBalance *rate.Limiter
GetSubAccountFundingBalance *rate.Limiter
SubAccountTransferHistory *rate.Limiter
MasterAccountsManageTransfersBetweenSubaccount *rate.Limiter
GetTickers *rate.Limiter
GetTicker *rate.Limiter
GetOrderbook *rate.Limiter
GetCandlesticks *rate.Limiter
GetCandlestickHistory *rate.Limiter
GetPublicTrades *rate.Limiter
GetPublicTradeHistrory *rate.Limiter
Get24HourTradingVolume *rate.Limiter
GetOracle *rate.Limiter
GetExchangeRate *rate.Limiter
GetInstrumentsRate *rate.Limiter
GetSystemTimeRate *rate.Limiter
GetSystemStatusRate *rate.Limiter
}
// Rate of requests per interval for each end point
const (
placeTradeOrderRate = 60
@@ -239,223 +163,77 @@ const (
getSystemStatusEPL
)
// Limit implements an endpoint limit.
func (r *RateLimit) Limit(ctx context.Context, ep request.EndpointLimit) error {
switch ep {
case placeTradeOrderEPL:
return r.PlaceTradeOrder.Wait(ctx)
case placeTradeMultipleOrdersEPL:
return r.PlaceTradeMultipleOrders.Wait(ctx)
case cancelTradeOrderEPL:
return r.CancelTradeOrder.Wait(ctx)
case cancelMultipleOrderEPL:
return r.CancelMultipleOrder.Wait(ctx)
case amendTradeOrderEPL:
return r.AmendTradeOrder.Wait(ctx)
case amendMultipleOrdersEPL:
return r.AmendMultipleOrders.Wait(ctx)
case getOrderDetailsEPL:
return r.GetOrderDetails.Wait(ctx)
case getOrderListEPL:
return r.GetOrderList.Wait(ctx)
case getOrderHistoryEPL:
return r.GetOrderHistory.Wait(ctx)
case getOrderhistory3MonthsEPL:
return r.GetOrderhistory3Months.Wait(ctx)
case getTransactionDetails3DaysEPL:
return r.GetTransactionDetails3Days.Wait(ctx)
case getTransactionDetails3MonthsEPL:
return r.GetTransactionDetails3Months.Wait(ctx)
case placeAlgoOrderEPL:
return r.PlaceAlgoOrder.Wait(ctx)
case cancelAlgoOrderEPL:
return r.CancelAlgoOrder.Wait(ctx)
case cancelAdvancedAlgoOrderEPL:
return r.CancelAdvancedAlgoOrder.Wait(ctx)
case getAlgoOrderListEPL:
return r.GetAlgoOrderList.Wait(ctx)
case getAlgoOrderHistoryEPL:
return r.GetAlgoOrderHistory.Wait(ctx)
case getFundingCurrenciesEPL:
return r.GetFundingCurrencies.Wait(ctx)
case getFundingAccountBalanceEPL:
return r.GetFundingAccountBalance.Wait(ctx)
case getAccountAssetValuationEPL:
return r.GetAccountAssetValuation.Wait(ctx)
case fundingTransferEPL:
return r.FundingTransfer.Wait(ctx)
case getFundsTransferStateEPL:
return r.GetFundsTransferState.Wait(ctx)
case assetBillsDetailEPL:
return r.AssetBillsDetail.Wait(ctx)
case lightningDepositsEPL:
return r.LightningDeposits.Wait(ctx)
case getAssetDepositAddressEPL:
return r.GetAssetDepositAddress.Wait(ctx)
case getDepositHistoryEPL:
return r.GetDepositHistory.Wait(ctx)
case postWithdrawalEPL:
return r.PostWithdrawal.Wait(ctx)
case postLightningWithdrawalEPL:
return r.PostLightningWithdrawal.Wait(ctx)
case cancelWithdrawalEPL:
return r.CancelWithdrawal.Wait(ctx)
case getAssetWithdrawalHistoryEPL:
return r.GetAssetWithdrawalHistory.Wait(ctx)
case getAccountBalanceEPL:
return r.GetAccountBalance.Wait(ctx)
case getBillsDetailLast3MonthEPL:
return r.GetBillsDetailLast3Month.Wait(ctx)
case getBillsDetailEPL:
return r.GetBillsDetail.Wait(ctx)
case getAccountConfigurationEPL:
return r.GetAccountConfiguration.Wait(ctx)
case getMaxBuySellAmountOpenAmountEPL:
return r.GetMaxBuySellAmountOpenAmount.Wait(ctx)
case getMaxAvailableTradableAmountEPL:
return r.GetMaxAvailableTradableAmount.Wait(ctx)
case getFeeRatesEPL:
return r.GetFeeRates.Wait(ctx)
case getMaxWithdrawalsEPL:
return r.GetMaxWithdrawals.Wait(ctx)
case getAvailablePairsEPL:
return r.GetAvailablePairs.Wait(ctx)
case requestQuotesEPL:
return r.RequestQuotes.Wait(ctx)
case placeRFQOrderEPL:
return r.PlaceRFQOrder.Wait(ctx)
case getRFQTradeOrderDetailsEPL:
return r.GetRFQTradeOrderDetails.Wait(ctx)
case getRFQTradeOrderHistoryEPL:
return r.GetRFQTradeOrderHistory.Wait(ctx)
case fiatDepositEPL:
return r.FiatDepositRate.Wait(ctx)
case fiatCancelDepositEPL:
return r.FiatCancelDepositRate.Wait(ctx)
case fiatDepositHistoryEPL:
return r.FiatDepositHistoryRate.Wait(ctx)
case fiatWithdrawalEPL:
return r.FiatWithdrawalRate.Wait(ctx)
case fiatCancelWithdrawalEPL:
return r.FiatCancelWithdrawalRate.Wait(ctx)
case fiatGetWithdrawalsEPL:
return r.FiatGetWithdrawalsRate.Wait(ctx)
case fiatGetChannelInfoEPL:
return r.FiatGetChannelInfoRate.Wait(ctx)
case subAccountsListEPL:
return r.SubAccountsList.Wait(ctx)
case getAPIKeyOfASubAccountEPL:
return r.GetAPIKeyOfASubAccount.Wait(ctx)
case getSubAccountTradingBalanceEPL:
return r.GetSubAccountTradingBalance.Wait(ctx)
case getSubAccountFundingBalanceEPL:
return r.GetSubAccountFundingBalance.Wait(ctx)
case subAccountTransferHistoryEPL:
return r.SubAccountTransferHistory.Wait(ctx)
case masterAccountsManageTransfersBetweenSubaccountEPL:
return r.MasterAccountsManageTransfersBetweenSubaccount.Wait(ctx)
case getTickersEPL:
return r.GetTickers.Wait(ctx)
case getTickerEPL:
return r.GetTicker.Wait(ctx)
case getOrderbookEPL:
return r.GetOrderbook.Wait(ctx)
case getCandlesticksEPL:
return r.GetCandlesticks.Wait(ctx)
case getCandlestickHistoryEPL:
return r.GetCandlestickHistory.Wait(ctx)
case getPublicTradesEPL:
return r.GetPublicTrades.Wait(ctx)
case getPublicTradeHistroryEPL:
return r.GetPublicTradeHistrory.Wait(ctx)
case get24HourTradingVolumeEPL:
return r.Get24HourTradingVolume.Wait(ctx)
case getOracleEPL:
return r.GetOracle.Wait(ctx)
case getExchangeRateEPL:
return r.GetExchangeRate.Wait(ctx)
case getInstrumentsEPL:
return r.GetInstrumentsRate.Wait(ctx)
case getSystemTimeEPL:
return r.GetSystemTimeRate.Wait(ctx)
case getSystemStatusEPL:
return r.GetSystemStatusRate.Wait(ctx)
default:
return errors.New("unknown endpoint limit")
}
}
// SetRateLimit returns a new RateLimit instance which implements request.Limiter interface.
func SetRateLimit() *RateLimit {
return &RateLimit{
PlaceTradeOrder: request.NewRateLimit(twoSecondsInterval, placeTradeOrderRate),
PlaceTradeMultipleOrders: request.NewRateLimit(twoSecondsInterval, placeTradeMultipleOrdersRate),
CancelTradeOrder: request.NewRateLimit(twoSecondsInterval, cancelTradeOrderRate),
CancelMultipleOrder: request.NewRateLimit(twoSecondsInterval, cancelMultipleOrderRate),
AmendTradeOrder: request.NewRateLimit(twoSecondsInterval, amendTradeOrderRate),
AmendMultipleOrders: request.NewRateLimit(twoSecondsInterval, amendMultipleOrdersRate),
GetOrderDetails: request.NewRateLimit(twoSecondsInterval, getOrderDetailsRate),
GetOrderList: request.NewRateLimit(twoSecondsInterval, getOrderListRate),
GetOrderHistory: request.NewRateLimit(twoSecondsInterval, getOrderHistoryRate),
GetOrderhistory3Months: request.NewRateLimit(twoSecondsInterval, getOrderhistory3MonthsRate),
GetTransactionDetails3Days: request.NewRateLimit(twoSecondsInterval, getTransactionDetails3DaysRate),
GetTransactionDetails3Months: request.NewRateLimit(twoSecondsInterval, getTransactionDetails3MonthsRate),
PlaceAlgoOrder: request.NewRateLimit(twoSecondsInterval, placeAlgoOrderRate),
CancelAlgoOrder: request.NewRateLimit(twoSecondsInterval, cancelAlgoOrderRate),
CancelAdvancedAlgoOrder: request.NewRateLimit(twoSecondsInterval, cancelAdvancedAlgoOrderRate),
GetAlgoOrderList: request.NewRateLimit(twoSecondsInterval, getAlgoOrderListRate),
GetAlgoOrderHistory: request.NewRateLimit(twoSecondsInterval, getAlgoOrderHistoryRate),
GetFundingCurrencies: request.NewRateLimit(oneSecondInterval, getFundingCurrenciesRate),
GetFundingAccountBalance: request.NewRateLimit(oneSecondInterval, getFundingAccountBalanceRate),
GetAccountAssetValuation: request.NewRateLimit(twoSecondsInterval, getAccountAssetValuationRate),
FundingTransfer: request.NewRateLimit(oneSecondInterval, fundingTransferRate),
GetFundsTransferState: request.NewRateLimit(oneSecondInterval, getFundsTransferStateRate),
AssetBillsDetail: request.NewRateLimit(oneSecondInterval, assetBillsDetailRate),
LightningDeposits: request.NewRateLimit(oneSecondInterval, lightningDepositsRate),
GetAssetDepositAddress: request.NewRateLimit(oneSecondInterval, getAssetDepositAddressRate),
GetDepositHistory: request.NewRateLimit(oneSecondInterval, getDepositHistoryRate),
PostWithdrawal: request.NewRateLimit(oneSecondInterval, postWithdrawalRate),
PostLightningWithdrawal: request.NewRateLimit(oneSecondInterval, postLightningWithdrawalRate),
CancelWithdrawal: request.NewRateLimit(oneSecondInterval, cancelWithdrawalRate),
GetAssetWithdrawalHistory: request.NewRateLimit(oneSecondInterval, getAssetWithdrawalHistoryRate),
GetAccountBalance: request.NewRateLimit(twoSecondsInterval, getAccountBalanceRate),
GetBillsDetailLast3Month: request.NewRateLimit(oneSecondInterval, getBillsDetailLast3MonthRate),
GetBillsDetail: request.NewRateLimit(oneSecondInterval, getBillsDetailRate),
GetAccountConfiguration: request.NewRateLimit(twoSecondsInterval, getAccountConfigurationRate),
GetMaxBuySellAmountOpenAmount: request.NewRateLimit(twoSecondsInterval, getMaxBuySellAmountOpenAmountRate),
GetMaxAvailableTradableAmount: request.NewRateLimit(twoSecondsInterval, getMaxAvailableTradableAmountRate),
GetFeeRates: request.NewRateLimit(twoSecondsInterval, getFeeRatesRate),
GetMaxWithdrawals: request.NewRateLimit(twoSecondsInterval, getMaxWithdrawalsRate),
GetAvailablePairs: request.NewRateLimit(oneSecondInterval, getAvailablePairsRate),
RequestQuotes: request.NewRateLimit(oneSecondInterval, requestQuotesRate),
PlaceRFQOrder: request.NewRateLimit(oneSecondInterval, placeRFQOrderRate),
GetRFQTradeOrderDetails: request.NewRateLimit(oneSecondInterval, getRFQTradeOrderDetailsRate),
GetRFQTradeOrderHistory: request.NewRateLimit(oneSecondInterval, getRFQTradeOrderHistoryRate),
FiatDepositRate: request.NewRateLimit(oneSecondInterval, fiatDepositRate),
FiatCancelDepositRate: request.NewRateLimit(twoSecondsInterval, fiatCancelDepositRate),
FiatDepositHistoryRate: request.NewRateLimit(oneSecondInterval, fiatDepositHistoryRate),
FiatWithdrawalRate: request.NewRateLimit(oneSecondInterval, fiatWithdrawalRate),
FiatCancelWithdrawalRate: request.NewRateLimit(twoSecondsInterval, fiatCancelWithdrawalRate),
FiatGetWithdrawalsRate: request.NewRateLimit(oneSecondInterval, fiatGetWithdrawalsRate),
FiatGetChannelInfoRate: request.NewRateLimit(oneSecondInterval, fiatGetChannelInfoRate),
SubAccountsList: request.NewRateLimit(twoSecondsInterval, subAccountsListRate),
GetAPIKeyOfASubAccount: request.NewRateLimit(oneSecondInterval, getAPIKeyOfASubAccountRate),
GetSubAccountTradingBalance: request.NewRateLimit(twoSecondsInterval, getSubAccountTradingBalanceRate),
GetSubAccountFundingBalance: request.NewRateLimit(twoSecondsInterval, getSubAccountFundingBalanceRate),
SubAccountTransferHistory: request.NewRateLimit(oneSecondInterval, subAccountTransferHistoryRate),
MasterAccountsManageTransfersBetweenSubaccount: request.NewRateLimit(oneSecondInterval, masterAccountsManageTransfersBetweenSubaccountRate),
GetTickers: request.NewRateLimit(twoSecondsInterval, getTickersRate),
GetTicker: request.NewRateLimit(twoSecondsInterval, getTickerRate),
GetOrderbook: request.NewRateLimit(twoSecondsInterval, getOrderbookRate),
GetCandlesticks: request.NewRateLimit(twoSecondsInterval, getCandlesticksRate),
GetCandlestickHistory: request.NewRateLimit(twoSecondsInterval, getCandlestickHistoryRate),
GetPublicTrades: request.NewRateLimit(twoSecondsInterval, getPublicTradesRate),
GetPublicTradeHistrory: request.NewRateLimit(twoSecondsInterval, getPublicTradeHistroryRate),
Get24HourTradingVolume: request.NewRateLimit(twoSecondsInterval, get24HourTradingVolumeRate),
GetOracle: request.NewRateLimit(fiveSecondsInterval, getOracleRate),
GetExchangeRate: request.NewRateLimit(twoSecondsInterval, getExchangeRateRate),
GetInstrumentsRate: request.NewRateLimit(twoSecondsInterval, getInstrumentsRate),
GetSystemTimeRate: request.NewRateLimit(twoSecondsInterval, getSystemTimeRate),
GetSystemStatusRate: request.NewRateLimit(fiveSecondsInterval, getSystemStatusRate),
// GetRateLimit returns a new RateLimit instance which implements request.Limiter interface.
func GetRateLimit() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
placeTradeOrderEPL: request.NewRateLimitWithWeight(twoSecondsInterval, placeTradeOrderRate, 1),
placeTradeMultipleOrdersEPL: request.NewRateLimitWithWeight(twoSecondsInterval, placeTradeMultipleOrdersRate, 1),
cancelTradeOrderEPL: request.NewRateLimitWithWeight(twoSecondsInterval, cancelTradeOrderRate, 1),
cancelMultipleOrderEPL: request.NewRateLimitWithWeight(twoSecondsInterval, cancelMultipleOrderRate, 1),
amendTradeOrderEPL: request.NewRateLimitWithWeight(twoSecondsInterval, amendTradeOrderRate, 1),
amendMultipleOrdersEPL: request.NewRateLimitWithWeight(twoSecondsInterval, amendMultipleOrdersRate, 1),
getOrderDetailsEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getOrderDetailsRate, 1),
getOrderListEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getOrderListRate, 1),
getOrderHistoryEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getOrderHistoryRate, 1),
getOrderhistory3MonthsEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getOrderhistory3MonthsRate, 1),
getTransactionDetails3DaysEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getTransactionDetails3DaysRate, 1),
getTransactionDetails3MonthsEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getTransactionDetails3MonthsRate, 1),
placeAlgoOrderEPL: request.NewRateLimitWithWeight(twoSecondsInterval, placeAlgoOrderRate, 1),
cancelAlgoOrderEPL: request.NewRateLimitWithWeight(twoSecondsInterval, cancelAlgoOrderRate, 1),
cancelAdvancedAlgoOrderEPL: request.NewRateLimitWithWeight(twoSecondsInterval, cancelAdvancedAlgoOrderRate, 1),
getAlgoOrderListEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getAlgoOrderListRate, 1),
getAlgoOrderHistoryEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getAlgoOrderHistoryRate, 1),
getFundingCurrenciesEPL: request.NewRateLimitWithWeight(oneSecondInterval, getFundingCurrenciesRate, 1),
getFundingAccountBalanceEPL: request.NewRateLimitWithWeight(oneSecondInterval, getFundingAccountBalanceRate, 1),
getAccountAssetValuationEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getAccountAssetValuationRate, 1),
fundingTransferEPL: request.NewRateLimitWithWeight(oneSecondInterval, fundingTransferRate, 1),
getFundsTransferStateEPL: request.NewRateLimitWithWeight(oneSecondInterval, getFundsTransferStateRate, 1),
assetBillsDetailEPL: request.NewRateLimitWithWeight(oneSecondInterval, assetBillsDetailRate, 1),
lightningDepositsEPL: request.NewRateLimitWithWeight(oneSecondInterval, lightningDepositsRate, 1),
getAssetDepositAddressEPL: request.NewRateLimitWithWeight(oneSecondInterval, getAssetDepositAddressRate, 1),
getDepositHistoryEPL: request.NewRateLimitWithWeight(oneSecondInterval, getDepositHistoryRate, 1),
postWithdrawalEPL: request.NewRateLimitWithWeight(oneSecondInterval, postWithdrawalRate, 1),
postLightningWithdrawalEPL: request.NewRateLimitWithWeight(oneSecondInterval, postLightningWithdrawalRate, 1),
cancelWithdrawalEPL: request.NewRateLimitWithWeight(oneSecondInterval, cancelWithdrawalRate, 1),
getAssetWithdrawalHistoryEPL: request.NewRateLimitWithWeight(oneSecondInterval, getAssetWithdrawalHistoryRate, 1),
getAccountBalanceEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getAccountBalanceRate, 1),
getBillsDetailLast3MonthEPL: request.NewRateLimitWithWeight(oneSecondInterval, getBillsDetailLast3MonthRate, 1),
getBillsDetailEPL: request.NewRateLimitWithWeight(oneSecondInterval, getBillsDetailRate, 1),
getAccountConfigurationEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getAccountConfigurationRate, 1),
getMaxBuySellAmountOpenAmountEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getMaxBuySellAmountOpenAmountRate, 1),
getMaxAvailableTradableAmountEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getMaxAvailableTradableAmountRate, 1),
getFeeRatesEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getFeeRatesRate, 1),
getMaxWithdrawalsEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getMaxWithdrawalsRate, 1),
getAvailablePairsEPL: request.NewRateLimitWithWeight(oneSecondInterval, getAvailablePairsRate, 1),
requestQuotesEPL: request.NewRateLimitWithWeight(oneSecondInterval, requestQuotesRate, 1),
placeRFQOrderEPL: request.NewRateLimitWithWeight(oneSecondInterval, placeRFQOrderRate, 1),
getRFQTradeOrderDetailsEPL: request.NewRateLimitWithWeight(oneSecondInterval, getRFQTradeOrderDetailsRate, 1),
getRFQTradeOrderHistoryEPL: request.NewRateLimitWithWeight(oneSecondInterval, getRFQTradeOrderHistoryRate, 1),
fiatDepositEPL: request.NewRateLimitWithWeight(oneSecondInterval, fiatDepositRate, 1),
fiatCancelDepositEPL: request.NewRateLimitWithWeight(twoSecondsInterval, fiatCancelDepositRate, 1),
fiatDepositHistoryEPL: request.NewRateLimitWithWeight(oneSecondInterval, fiatDepositHistoryRate, 1),
fiatWithdrawalEPL: request.NewRateLimitWithWeight(oneSecondInterval, fiatWithdrawalRate, 1),
fiatCancelWithdrawalEPL: request.NewRateLimitWithWeight(twoSecondsInterval, fiatCancelWithdrawalRate, 1),
fiatGetWithdrawalsEPL: request.NewRateLimitWithWeight(oneSecondInterval, fiatGetWithdrawalsRate, 1),
fiatGetChannelInfoEPL: request.NewRateLimitWithWeight(oneSecondInterval, fiatGetChannelInfoRate, 1),
subAccountsListEPL: request.NewRateLimitWithWeight(twoSecondsInterval, subAccountsListRate, 1),
getAPIKeyOfASubAccountEPL: request.NewRateLimitWithWeight(oneSecondInterval, getAPIKeyOfASubAccountRate, 1),
getSubAccountTradingBalanceEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getSubAccountTradingBalanceRate, 1),
getSubAccountFundingBalanceEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getSubAccountFundingBalanceRate, 1),
subAccountTransferHistoryEPL: request.NewRateLimitWithWeight(oneSecondInterval, subAccountTransferHistoryRate, 1),
masterAccountsManageTransfersBetweenSubaccountEPL: request.NewRateLimitWithWeight(oneSecondInterval, masterAccountsManageTransfersBetweenSubaccountRate, 1),
getTickersEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getTickersRate, 1),
getTickerEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getTickerRate, 1),
getOrderbookEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getOrderbookRate, 1),
getCandlesticksEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getCandlesticksRate, 1),
getCandlestickHistoryEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getCandlestickHistoryRate, 1),
getPublicTradesEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getPublicTradesRate, 1),
getPublicTradeHistroryEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getPublicTradeHistroryRate, 1),
get24HourTradingVolumeEPL: request.NewRateLimitWithWeight(twoSecondsInterval, get24HourTradingVolumeRate, 1),
getOracleEPL: request.NewRateLimitWithWeight(fiveSecondsInterval, getOracleRate, 1),
getExchangeRateEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getExchangeRateRate, 1),
getInstrumentsEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getInstrumentsRate, 1),
getSystemTimeEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getSystemTimeRate, 1),
getSystemStatusEPL: request.NewRateLimitWithWeight(fiveSecondsInterval, getSystemStatusRate, 1),
}
}

View File

@@ -116,7 +116,7 @@ func (o *Okcoin) SetDefaults() {
}
o.Requester, err = request.New(o.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()),
request.WithLimiter(GetRateLimit()),
)
if err != nil {
log.Errorln(log.ExchangeSys, err)

View File

@@ -3140,7 +3140,7 @@ func (ok *Okx) GetIntervalEnum(interval kline.Interval, appendUTC bool) string {
// GetCandlesticks Retrieve the candlestick charts. This endpoint can retrieve the latest 1,440 data entries. Charts are returned in groups based on the requested bar.
func (ok *Okx) GetCandlesticks(ctx context.Context, instrumentID string, interval kline.Interval, before, after time.Time, limit int64) ([]CandleStick, error) {
return ok.GetCandlestickData(ctx, instrumentID, interval, before, after, limit, marketCandles, getCandlesticksEPL)
return ok.GetCandlestickData(ctx, instrumentID, interval, before, after, limit, marketCandles, getCandlestickEPL)
}
// GetCandlesticksHistory Retrieve history candlestick charts from recent years.
@@ -3151,7 +3151,7 @@ func (ok *Okx) GetCandlesticksHistory(ctx context.Context, instrumentID string,
// GetIndexCandlesticks Retrieve the candlestick charts of the index. This endpoint can retrieve the latest 1,440 data entries. Charts are returned in groups based on the requested bar.
// the response is a list of Candlestick data.
func (ok *Okx) GetIndexCandlesticks(ctx context.Context, instrumentID string, interval kline.Interval, before, after time.Time, limit int64) ([]CandleStick, error) {
return ok.GetCandlestickData(ctx, instrumentID, interval, before, after, limit, marketCandlesIndex, getIndexCandlesticksEPL)
return ok.GetCandlestickData(ctx, instrumentID, interval, before, after, limit, marketCandlesIndex, getIndexCandlestickEPL)
}
// GetMarkPriceCandlesticks Retrieve the candlestick charts of mark price. This endpoint can retrieve the latest 1,440 data entries. Charts are returned in groups based on the requested bar.
@@ -3488,7 +3488,7 @@ func (ok *Okx) GetEstimatedDeliveryPrice(ctx context.Context, instrumentID strin
return nil, errMissingRequiredParamInstID
}
params.Set("instId", instrumentID)
return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getEstimatedDeliveryPriceEPL, http.MethodGet, common.EncodeURLValues(publicEstimatedPrice, params), nil, &resp, false)
return resp, ok.SendHTTPRequest(ctx, exchange.RestSpot, getEstimatedDeliveryExercisePriceEPL, http.MethodGet, common.EncodeURLValues(publicEstimatedPrice, params), nil, &resp, false)
}
// GetDiscountRateAndInterestFreeQuota retrieves discount rate level and interest-free quota.

View File

@@ -989,7 +989,7 @@ func TestCancelAllQuotes(t *testing.T) {
switch {
case err != nil:
t.Error("Okx CancelAllQuotes() error", err)
case err == nil && time.IsZero():
case time.IsZero():
t.Error("Okx CancelAllQuotes() zero timestamp message ")
}
}
@@ -2237,7 +2237,7 @@ func TestGetOrderHistory(t *testing.T) {
_, err := ok.GetOrderHistory(contextGenerate(), &getOrdersRequest)
if err == nil {
t.Errorf("Okx GetOrderHistory() Expected: %v. received nil", err)
} else if err != nil && !errors.Is(err, errMissingAtLeast1CurrencyPair) {
} else if !errors.Is(err, errMissingAtLeast1CurrencyPair) {
t.Errorf("Okx GetOrderHistory() Expected: %v, but found %v", errMissingAtLeast1CurrencyPair, err)
}
getOrdersRequest.Pairs = []currency.Pair{

View File

@@ -1829,9 +1829,6 @@ func (ok *Okx) wsChannelSubscription(operation, channel string, assetType asset.
return errIncompleteCurrencyPair
}
instrumentID = format.Format(pair)
if err != nil {
instrumentID = ""
}
}
input := &SubscriptionOperationInput{
Operation: operation,
@@ -1885,9 +1882,6 @@ func (ok *Okx) wsAuthChannelSubscription(operation, channel string, assetType as
return errIncompleteCurrencyPair
}
instrumentID = format.Format(pair)
if err != nil {
instrumentID = ""
}
}
if params.Currency {
if !pair.IsEmpty() {

View File

@@ -154,7 +154,7 @@ func (ok *Okx) SetDefaults() {
}
ok.Requester, err = request.New(ok.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
request.WithLimiter(GetRateLimit()))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}
@@ -820,12 +820,8 @@ func (ok *Okx) ModifyOrder(ctx context.Context, action *order.Modify) (*order.Mo
if action.Pair.IsEmpty() {
return nil, currency.ErrCurrencyPairEmpty
}
instrumentID := pairFormat.Format(action.Pair)
if err != nil {
return nil, err
}
amendRequest := AmendOrderRequestParams{
InstrumentID: instrumentID,
InstrumentID: pairFormat.Format(action.Pair),
NewQuantity: action.Amount,
OrderID: action.OrderID,
ClientOrderID: action.ClientOrderID,
@@ -888,8 +884,6 @@ func (ok *Okx) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.
if !ok.SupportsAsset(ord.AssetType) {
return nil, fmt.Errorf("%w: %v", asset.ErrNotSupported, ord.AssetType)
}
var instrumentID string
var pairFormat currency.PairFormat
pairFormat, err = ok.GetPairFormat(ord.AssetType, true)
if err != nil {
@@ -898,12 +892,8 @@ func (ok *Okx) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*order.
if !ord.Pair.IsPopulated() {
return nil, errIncompleteCurrencyPair
}
instrumentID = pairFormat.Format(ord.Pair)
if err != nil {
return nil, err
}
cancelOrderParams[x] = CancelOrderRequestParam{
InstrumentID: instrumentID,
InstrumentID: pairFormat.Format(ord.Pair),
OrderID: ord.OrderID,
ClientOrderID: ord.ClientOrderID,
}

View File

@@ -1,12 +1,9 @@
package okx
import (
"context"
"errors"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
// Ratelimit intervals.
@@ -18,182 +15,6 @@ const (
tenSecondsInterval = 10 * time.Second
)
// RateLimit implements the request.Limiter interface
type RateLimit struct {
// Trade Endpoints
PlaceOrder *rate.Limiter
PlaceMultipleOrders *rate.Limiter
CancelOrder *rate.Limiter
CancelMultipleOrders *rate.Limiter
AmendOrder *rate.Limiter
AmendMultipleOrders *rate.Limiter
CloseDeposit *rate.Limiter
GetOrderDetails *rate.Limiter
GetOrderList *rate.Limiter
GetOrderHistory7Days *rate.Limiter
GetOrderHistory3Months *rate.Limiter
GetTransactionDetail3Days *rate.Limiter
GetTransactionDetail3Months *rate.Limiter
PlaceAlgoOrder *rate.Limiter
CancelAlgoOrder *rate.Limiter
CancelAdvanceAlgoOrder *rate.Limiter
GetAlgoOrderList *rate.Limiter
GetAlgoOrderHistory *rate.Limiter
GetEasyConvertCurrencyList *rate.Limiter
PlaceEasyConvert *rate.Limiter
GetEasyConvertHistory *rate.Limiter
GetOneClickRepayHistory *rate.Limiter
OneClickRepayCurrencyList *rate.Limiter
TradeOneClickRepay *rate.Limiter
// Block Trading endpoints
GetCounterparties *rate.Limiter
CreateRfq *rate.Limiter
CancelRfq *rate.Limiter
CancelMultipleRfq *rate.Limiter
CancelAllRfqs *rate.Limiter
ExecuteQuote *rate.Limiter
SetQuoteProducts *rate.Limiter
RestMMPStatus *rate.Limiter
CreateQuote *rate.Limiter
CancelQuote *rate.Limiter
CancelMultipleQuotes *rate.Limiter
CancelAllQuotes *rate.Limiter
GetRfqs *rate.Limiter
GetQuotes *rate.Limiter
GetTrades *rate.Limiter
GetTradesHistory *rate.Limiter
GetPublicTrades *rate.Limiter
// Funding
GetCurrencies *rate.Limiter
GetBalance *rate.Limiter
GetAccountAssetValuation *rate.Limiter
FundsTransfer *rate.Limiter
GetFundsTransferState *rate.Limiter
AssetBillsDetails *rate.Limiter
LightningDeposits *rate.Limiter
GetDepositAddress *rate.Limiter
GetDepositHistory *rate.Limiter
Withdrawal *rate.Limiter
LightningWithdrawals *rate.Limiter
CancelWithdrawal *rate.Limiter
GetWithdrawalHistory *rate.Limiter
SmallAssetsConvert *rate.Limiter
// Savings
GetSavingBalance *rate.Limiter
SavingsPurchaseRedempt *rate.Limiter
SetLendingRate *rate.Limiter
GetLendingHistory *rate.Limiter
GetPublicBorrowInfo *rate.Limiter
GetPublicBorrowHistory *rate.Limiter
// Convert
GetConvertCurrencies *rate.Limiter
GetConvertCurrencyPair *rate.Limiter
EstimateQuote *rate.Limiter
ConvertTrade *rate.Limiter
GetConvertHistory *rate.Limiter
// Account
GetAccountBalance *rate.Limiter
GetPositions *rate.Limiter
GetPositionsHistory *rate.Limiter
GetAccountAndPositionRisk *rate.Limiter
GetBillsDetails *rate.Limiter
GetAccountConfiguration *rate.Limiter
SetPositionMode *rate.Limiter
SetLeverage *rate.Limiter
GetMaximumBuyOrSellAmount *rate.Limiter
GetMaximumAvailableTradableAmount *rate.Limiter
IncreaseOrDecreaseMargin *rate.Limiter
GetLeverage *rate.Limiter
GetTheMaximumLoanOfInstrument *rate.Limiter
GetFeeRates *rate.Limiter
GetInterestAccruedData *rate.Limiter
GetInterestRate *rate.Limiter
SetGreeks *rate.Limiter
IsolatedMarginTradingSettings *rate.Limiter
GetMaximumWithdrawals *rate.Limiter
GetAccountRiskState *rate.Limiter
VipLoansBorrowAnsRepay *rate.Limiter
GetBorrowAnsRepayHistoryHistory *rate.Limiter
GetBorrowInterestAndLimit *rate.Limiter
PositionBuilder *rate.Limiter
GetGreeks *rate.Limiter
GetPMLimitation *rate.Limiter
// Sub Account Endpoints
ViewSubaccountList *rate.Limiter
ResetSubAccountAPIKey *rate.Limiter
GetSubaccountTradingBalance *rate.Limiter
GetSubaccountFundingBalance *rate.Limiter
HistoryOfSubaccountTransfer *rate.Limiter
MasterAccountsManageTransfersBetweenSubaccount *rate.Limiter
SetPermissionOfTransferOut *rate.Limiter
GetCustodyTradingSubaccountList *rate.Limiter
GridTrading *rate.Limiter
AmendGridAlgoOrder *rate.Limiter
StopGridAlgoOrder *rate.Limiter
GetGridAlgoOrderList *rate.Limiter
GetGridAlgoOrderHistory *rate.Limiter
GetGridAlgoOrderDetails *rate.Limiter
GetGridAlgoSubOrders *rate.Limiter
GetGridAlgoOrderPositions *rate.Limiter
SpotGridWithdrawIncome *rate.Limiter
ComputeMarginBalance *rate.Limiter
AdjustMarginBalance *rate.Limiter
GetGridAIParameter *rate.Limiter
// Earn
GetOffer *rate.Limiter
Purchase *rate.Limiter
Redeem *rate.Limiter
CancelPurchaseOrRedemption *rate.Limiter
GetEarnActiveOrders *rate.Limiter
GetFundingOrderHistory *rate.Limiter
// Market Data
GetTickers *rate.Limiter
GetIndexTickers *rate.Limiter
GetOrderBook *rate.Limiter
GetCandlesticks *rate.Limiter
GetCandlesticksHistory *rate.Limiter
GetIndexCandlesticks *rate.Limiter
GetMarkPriceCandlesticks *rate.Limiter
GetTradesRequest *rate.Limiter
Get24HTotalVolume *rate.Limiter
GetOracle *rate.Limiter
GetExchangeRateRequest *rate.Limiter
GetIndexComponents *rate.Limiter
GetBlockTickers *rate.Limiter
GetBlockTrades *rate.Limiter
// Public Data Endpoints
GetInstruments *rate.Limiter
GetDeliveryExerciseHistory *rate.Limiter
GetOpenInterest *rate.Limiter
GetFunding *rate.Limiter
GetFundingRateHistory *rate.Limiter
GetLimitPrice *rate.Limiter
GetOptionMarketDate *rate.Limiter
GetEstimatedDeliveryExercisePrice *rate.Limiter
GetDiscountRateAndInterestFreeQuota *rate.Limiter
GetSystemTime *rate.Limiter
GetLiquidationOrders *rate.Limiter
GetMarkPrice *rate.Limiter
GetPositionTiers *rate.Limiter
GetInterestRateAndLoanQuota *rate.Limiter
GetInterestRateAndLoanQuoteForVIPLoans *rate.Limiter
GetUnderlying *rate.Limiter
GetInsuranceFund *rate.Limiter
UnitConvert *rate.Limiter
// Trading Data Endpoints
GetSupportCoin *rate.Limiter
GetTakerVolume *rate.Limiter
GetMarginLendingRatio *rate.Limiter
GetLongShortRatio *rate.Limiter
GetContractsOpenInterestAndVolume *rate.Limiter
GetOptionsOpenInterestAndVolume *rate.Limiter
GetPutCallRatio *rate.Limiter
GetOpenInterestAndVolume *rate.Limiter
GetTakerFlow *rate.Limiter
// Status Endpoints
GetEventStatus *rate.Limiter
}
const (
// Trade Endpoints
placeOrderRate = 60
@@ -202,7 +23,7 @@ const (
cancelMultipleOrdersRate = 300
amendOrderRate = 60
amendMultipleOrdersRate = 300
closeDepositions = 20
closePositionsRate = 20
getOrderDetails = 60
getOrderListRate = 60
getOrderHistory7DaysRate = 40
@@ -502,7 +323,7 @@ const (
getTickersEPL
getIndexTickersEPL
getOrderBookEPL
getCandlesticksEPL
getCandlestickEPL
getTradesRequestEPL
get24HTotalVolumeEPL
getOracleEPL
@@ -517,7 +338,7 @@ const (
getFundingRateHistoryEPL
getLimitPriceEPL
getOptionMarketDateEPL
getEstimatedDeliveryPriceEPL
getEstimatedDeliveryExercisePriceEPL
getDiscountRateAndInterestFreeQuotaEPL
getSystemTimeEPL
getLiquidationOrdersEPL
@@ -539,519 +360,192 @@ const (
getTakerFlowEPL
getEventStatusEPL
getCandlestickHistoryEPL
getIndexCandlesticksEPL
getIndexCandlestickEPL
)
// Limit executes rate limiting for Okx exchange given the context and EndpointLimit
func (r *RateLimit) Limit(ctx context.Context, f request.EndpointLimit) error {
switch f {
case placeOrderEPL:
return r.PlaceOrder.Wait(ctx)
case placeMultipleOrdersEPL:
return r.PlaceMultipleOrders.Wait(ctx)
case cancelOrderEPL:
return r.CancelOrder.Wait(ctx)
case cancelMultipleOrdersEPL:
return r.CancelMultipleOrders.Wait(ctx)
case amendOrderEPL:
return r.AmendOrder.Wait(ctx)
case amendMultipleOrdersEPL:
return r.AmendMultipleOrders.Wait(ctx)
case closePositionEPL:
return r.CloseDeposit.Wait(ctx)
case getOrderDetEPL:
return r.GetOrderDetails.Wait(ctx)
case getOrderListEPL:
return r.GetOrderList.Wait(ctx)
case getOrderHistory7DaysEPL:
return r.GetOrderHistory7Days.Wait(ctx)
case getOrderHistory3MonthsEPL:
return r.GetOrderHistory3Months.Wait(ctx)
case getTransactionDetail3DaysEPL:
return r.GetTransactionDetail3Days.Wait(ctx)
case getTransactionDetail3MonthsEPL:
return r.GetTransactionDetail3Months.Wait(ctx)
case placeAlgoOrderEPL:
return r.PlaceAlgoOrder.Wait(ctx)
case cancelAlgoOrderEPL:
return r.CancelAlgoOrder.Wait(ctx)
case cancelAdvanceAlgoOrderEPL:
return r.CancelAdvanceAlgoOrder.Wait(ctx)
case getAlgoOrderListEPL:
return r.GetAlgoOrderList.Wait(ctx)
case getAlgoOrderHistoryEPL:
return r.GetAlgoOrderHistory.Wait(ctx)
case getEasyConvertCurrencyListEPL:
return r.GetEasyConvertCurrencyList.Wait(ctx)
case placeEasyConvertEPL:
return r.PlaceEasyConvert.Wait(ctx)
case getEasyConvertHistoryEPL:
return r.GetEasyConvertHistory.Wait(ctx)
case getOneClickRepayHistoryEPL:
return r.GetOneClickRepayHistory.Wait(ctx)
case oneClickRepayCurrencyListEPL:
return r.OneClickRepayCurrencyList.Wait(ctx)
case tradeOneClickRepayEPL:
return r.TradeOneClickRepay.Wait(ctx)
case getCounterpartiesEPL:
return r.GetCounterparties.Wait(ctx)
case createRfqEPL:
return r.CreateRfq.Wait(ctx)
case cancelRfqEPL:
return r.CancelRfq.Wait(ctx)
case cancelMultipleRfqEPL:
return r.CancelMultipleRfq.Wait(ctx)
case cancelAllRfqsEPL:
return r.CancelAllRfqs.Wait(ctx)
case executeQuoteEPL:
return r.ExecuteQuote.Wait(ctx)
case setQuoteProductsEPL:
return r.SetQuoteProducts.Wait(ctx)
case restMMPStatusEPL:
return r.RestMMPStatus.Wait(ctx)
case createQuoteEPL:
return r.CreateQuote.Wait(ctx)
case cancelQuoteEPL:
return r.CancelQuote.Wait(ctx)
case cancelMultipleQuotesEPL:
return r.CancelMultipleQuotes.Wait(ctx)
case cancelAllQuotesEPL:
return r.CancelAllQuotes.Wait(ctx)
case getRfqsEPL:
return r.GetRfqs.Wait(ctx)
case getQuotesEPL:
return r.GetQuotes.Wait(ctx)
case getTradesEPL:
return r.GetTrades.Wait(ctx)
case getTradesHistoryEPL:
return r.GetTradesHistory.Wait(ctx)
case getPublicTradesEPL:
return r.GetPublicTrades.Wait(ctx)
case getCurrenciesEPL:
return r.GetCurrencies.Wait(ctx)
case getBalanceEPL:
return r.GetBalance.Wait(ctx)
case getAccountAssetValuationEPL:
return r.GetAccountAssetValuation.Wait(ctx)
case fundsTransferEPL:
return r.FundsTransfer.Wait(ctx)
case getFundsTransferStateEPL:
return r.GetFundsTransferState.Wait(ctx)
case assetBillsDetailsEPL:
return r.AssetBillsDetails.Wait(ctx)
case lightningDepositsEPL:
return r.LightningDeposits.Wait(ctx)
case getDepositAddressEPL:
return r.GetDepositAddress.Wait(ctx)
case getDepositHistoryEPL:
return r.GetDepositHistory.Wait(ctx)
case withdrawalEPL:
return r.Withdrawal.Wait(ctx)
case lightningWithdrawalsEPL:
return r.LightningWithdrawals.Wait(ctx)
case cancelWithdrawalEPL:
return r.CancelWithdrawal.Wait(ctx)
case getWithdrawalHistoryEPL:
return r.GetWithdrawalHistory.Wait(ctx)
case smallAssetsConvertEPL:
return r.SmallAssetsConvert.Wait(ctx)
case getSavingBalanceEPL:
return r.GetSavingBalance.Wait(ctx)
case savingsPurchaseRedemptionEPL:
return r.SavingsPurchaseRedempt.Wait(ctx)
case setLendingRateEPL:
return r.SetLendingRate.Wait(ctx)
case getLendingHistoryEPL:
return r.GetLendingHistory.Wait(ctx)
case getPublicBorrowInfoEPL:
return r.GetPublicBorrowInfo.Wait(ctx)
case getPublicBorrowHistoryEPL:
return r.GetPublicBorrowHistory.Wait(ctx)
case getConvertCurrenciesEPL:
return r.GetConvertCurrencies.Wait(ctx)
case getConvertCurrencyPairEPL:
return r.GetConvertCurrencyPair.Wait(ctx)
case estimateQuoteEPL:
return r.EstimateQuote.Wait(ctx)
case convertTradeEPL:
return r.ConvertTrade.Wait(ctx)
case getConvertHistoryEPL:
return r.GetConvertHistory.Wait(ctx)
case getAccountBalanceEPL:
return r.GetAccountBalance.Wait(ctx)
case getPositionsEPL:
return r.GetPositions.Wait(ctx)
case getPositionsHistoryEPL:
return r.GetPositionsHistory.Wait(ctx)
case getAccountAndPositionRiskEPL:
return r.GetAccountAndPositionRisk.Wait(ctx)
case getBillsDetailsEPL:
return r.GetBillsDetails.Wait(ctx)
case getAccountConfigurationEPL:
return r.GetAccountConfiguration.Wait(ctx)
case setPositionModeEPL:
return r.SetPositionMode.Wait(ctx)
case setLeverageEPL:
return r.SetLeverage.Wait(ctx)
case getMaximumBuyOrSellAmountEPL:
return r.GetMaximumBuyOrSellAmount.Wait(ctx)
case getMaximumAvailableTradableAmountEPL:
return r.GetMaximumAvailableTradableAmount.Wait(ctx)
case increaseOrDecreaseMarginEPL:
return r.IncreaseOrDecreaseMargin.Wait(ctx)
case getLeverageEPL:
return r.GetLeverage.Wait(ctx)
case getTheMaximumLoanOfInstrumentEPL:
return r.GetTheMaximumLoanOfInstrument.Wait(ctx)
case getFeeRatesEPL:
return r.GetFeeRates.Wait(ctx)
case getInterestAccruedDataEPL:
return r.GetInterestAccruedData.Wait(ctx)
case getInterestRateEPL:
return r.GetInterestRate.Wait(ctx)
case setGreeksEPL:
return r.SetGreeks.Wait(ctx)
case isolatedMarginTradingSettingsEPL:
return r.IsolatedMarginTradingSettings.Wait(ctx)
case getMaximumWithdrawalsEPL:
return r.GetMaximumWithdrawals.Wait(ctx)
case getAccountRiskStateEPL:
return r.GetAccountRiskState.Wait(ctx)
case vipLoansBorrowAnsRepayEPL:
return r.VipLoansBorrowAnsRepay.Wait(ctx)
case getBorrowAnsRepayHistoryHistoryEPL:
return r.GetBorrowAnsRepayHistoryHistory.Wait(ctx)
case getBorrowInterestAndLimitEPL:
return r.GetBorrowInterestAndLimit.Wait(ctx)
case positionBuilderEPL:
return r.PositionBuilder.Wait(ctx)
case getGreeksEPL:
return r.GetGreeks.Wait(ctx)
case getPMLimitationEPL:
return r.GetPMLimitation.Wait(ctx)
case viewSubaccountListEPL:
return r.ViewSubaccountList.Wait(ctx)
case resetSubAccountAPIKeyEPL:
return r.ResetSubAccountAPIKey.Wait(ctx)
case getSubaccountTradingBalanceEPL:
return r.GetSubaccountTradingBalance.Wait(ctx)
case getSubaccountFundingBalanceEPL:
return r.GetSubaccountFundingBalance.Wait(ctx)
case historyOfSubaccountTransferEPL:
return r.HistoryOfSubaccountTransfer.Wait(ctx)
case masterAccountsManageTransfersBetweenSubaccountEPL:
return r.MasterAccountsManageTransfersBetweenSubaccount.Wait(ctx)
case setPermissionOfTransferOutEPL:
return r.SetPermissionOfTransferOut.Wait(ctx)
case getCustodyTradingSubaccountListEPL:
return r.GetCustodyTradingSubaccountList.Wait(ctx)
case gridTradingEPL:
return r.GridTrading.Wait(ctx)
case amendGridAlgoOrderEPL:
return r.AmendGridAlgoOrder.Wait(ctx)
case stopGridAlgoOrderEPL:
return r.StopGridAlgoOrder.Wait(ctx)
case getGridAlgoOrderListEPL:
return r.GetGridAlgoOrderList.Wait(ctx)
case getGridAlgoOrderHistoryEPL:
return r.GetGridAlgoOrderHistory.Wait(ctx)
case getGridAlgoOrderDetailsEPL:
return r.GetGridAlgoOrderDetails.Wait(ctx)
case getGridAlgoSubOrdersEPL:
return r.GetGridAlgoSubOrders.Wait(ctx)
case getGridAlgoOrderPositionsEPL:
return r.GetGridAlgoOrderPositions.Wait(ctx)
case spotGridWithdrawIncomeEPL:
return r.SpotGridWithdrawIncome.Wait(ctx)
case computeMarginBalanceEPL:
return r.ComputeMarginBalance.Wait(ctx)
case adjustMarginBalanceEPL:
return r.AdjustMarginBalance.Wait(ctx)
case getGridAIParameterEPL:
return r.GetGridAIParameter.Wait(ctx)
case getOfferEPL:
return r.GetOffer.Wait(ctx)
case purchaseEPL:
return r.Purchase.Wait(ctx)
case redeemEPL:
return r.Redeem.Wait(ctx)
case cancelPurchaseOrRedemptionEPL:
return r.CancelPurchaseOrRedemption.Wait(ctx)
case getEarnActiveOrdersEPL:
return r.GetEarnActiveOrders.Wait(ctx)
case getFundingOrderHistoryEPL:
return r.GetFundingOrderHistory.Wait(ctx)
case getTickersEPL:
return r.GetTickers.Wait(ctx)
case getIndexTickersEPL:
return r.GetIndexTickers.Wait(ctx)
case getOrderBookEPL:
return r.GetOrderBook.Wait(ctx)
case getCandlesticksEPL:
return r.GetCandlesticks.Wait(ctx)
case getCandlestickHistoryEPL:
return r.GetCandlesticksHistory.Wait(ctx)
case getIndexCandlesticksEPL:
return r.GetIndexCandlesticks.Wait(ctx)
case getTradesRequestEPL:
return r.GetTradesRequest.Wait(ctx)
case get24HTotalVolumeEPL:
return r.Get24HTotalVolume.Wait(ctx)
case getOracleEPL:
return r.GetOracle.Wait(ctx)
case getExchangeRateRequestEPL:
return r.GetExchangeRateRequest.Wait(ctx)
case getIndexComponentsEPL:
return r.GetIndexComponents.Wait(ctx)
case getBlockTickersEPL:
return r.GetBlockTickers.Wait(ctx)
case getBlockTradesEPL:
return r.GetBlockTrades.Wait(ctx)
case getInstrumentsEPL:
return r.GetInstruments.Wait(ctx)
case getDeliveryExerciseHistoryEPL:
return r.GetDeliveryExerciseHistory.Wait(ctx)
case getOpenInterestEPL:
return r.GetOpenInterest.Wait(ctx)
case getFundingEPL:
return r.GetFunding.Wait(ctx)
case getFundingRateHistoryEPL:
return r.GetFundingRateHistory.Wait(ctx)
case getLimitPriceEPL:
return r.GetLimitPrice.Wait(ctx)
case getOptionMarketDateEPL:
return r.GetOptionMarketDate.Wait(ctx)
case getEstimatedDeliveryPriceEPL:
return r.GetEstimatedDeliveryExercisePrice.Wait(ctx)
case getDiscountRateAndInterestFreeQuotaEPL:
return r.GetDiscountRateAndInterestFreeQuota.Wait(ctx)
case getSystemTimeEPL:
return r.GetSystemTime.Wait(ctx)
case getLiquidationOrdersEPL:
return r.GetLiquidationOrders.Wait(ctx)
case getMarkPriceEPL:
return r.GetMarkPrice.Wait(ctx)
case getPositionTiersEPL:
return r.GetPositionTiers.Wait(ctx)
case getInterestRateAndLoanQuotaEPL:
return r.GetInterestRateAndLoanQuota.Wait(ctx)
case getInterestRateAndLoanQuoteForVIPLoansEPL:
return r.GetInterestRateAndLoanQuoteForVIPLoans.Wait(ctx)
case getUnderlyingEPL:
return r.GetUnderlying.Wait(ctx)
case getInsuranceFundEPL:
return r.GetInsuranceFund.Wait(ctx)
case unitConvertEPL:
return r.UnitConvert.Wait(ctx)
case getSupportCoinEPL:
return r.GetSupportCoin.Wait(ctx)
case getTakerVolumeEPL:
return r.GetTakerVolume.Wait(ctx)
case getMarginLendingRatioEPL:
return r.GetMarginLendingRatio.Wait(ctx)
case getLongShortRatioEPL:
return r.GetLongShortRatio.Wait(ctx)
case getContractsOpenInterestAndVolumeEPL:
return r.GetContractsOpenInterestAndVolume.Wait(ctx)
case getOptionsOpenInterestAndVolumeEPL:
return r.GetOptionsOpenInterestAndVolume.Wait(ctx)
case getPutCallRatioEPL:
return r.GetPutCallRatio.Wait(ctx)
case getOpenInterestAndVolumeEPL:
return r.GetOpenInterestAndVolume.Wait(ctx)
case getTakerFlowEPL:
return r.GetTakerFlow.Wait(ctx)
case getEventStatusEPL:
return r.GetEventStatus.Wait(ctx)
default:
return errors.New("endpoint rate limit functionality not found")
}
}
// SetRateLimit returns a RateLimit instance, which implements the request.Limiter interface.
func SetRateLimit() *RateLimit {
return &RateLimit{
// GetRateLimit returns a RateLimit instance, which implements the request.Limiter interface.
func GetRateLimit() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
// Trade Endpoints
PlaceOrder: request.NewRateLimit(twoSecondsInterval, placeOrderRate),
PlaceMultipleOrders: request.NewRateLimit(twoSecondsInterval, placeMultipleOrdersRate),
CancelOrder: request.NewRateLimit(twoSecondsInterval, cancelOrderRate),
CancelMultipleOrders: request.NewRateLimit(twoSecondsInterval, cancelMultipleOrdersRate),
AmendOrder: request.NewRateLimit(twoSecondsInterval, amendOrderRate),
AmendMultipleOrders: request.NewRateLimit(twoSecondsInterval, amendMultipleOrdersRate),
CloseDeposit: request.NewRateLimit(twoSecondsInterval, closeDepositions),
GetOrderDetails: request.NewRateLimit(twoSecondsInterval, getOrderDetails),
GetOrderList: request.NewRateLimit(twoSecondsInterval, getOrderListRate),
GetOrderHistory7Days: request.NewRateLimit(twoSecondsInterval, getOrderHistory7DaysRate),
GetOrderHistory3Months: request.NewRateLimit(twoSecondsInterval, getOrderHistory3MonthsRate),
GetTransactionDetail3Days: request.NewRateLimit(twoSecondsInterval, getTransactionDetail3DaysRate),
GetTransactionDetail3Months: request.NewRateLimit(twoSecondsInterval, getTransactionDetail3MonthsRate),
PlaceAlgoOrder: request.NewRateLimit(twoSecondsInterval, placeAlgoOrderRate),
CancelAlgoOrder: request.NewRateLimit(twoSecondsInterval, cancelAlgoOrderRate),
CancelAdvanceAlgoOrder: request.NewRateLimit(twoSecondsInterval, cancelAdvanceAlgoOrderRate),
GetAlgoOrderList: request.NewRateLimit(twoSecondsInterval, getAlgoOrderListRate),
GetAlgoOrderHistory: request.NewRateLimit(twoSecondsInterval, getAlgoOrderHistoryRate),
GetEasyConvertCurrencyList: request.NewRateLimit(twoSecondsInterval, getEasyConvertCurrencyListRate),
PlaceEasyConvert: request.NewRateLimit(twoSecondsInterval, placeEasyConvert),
GetEasyConvertHistory: request.NewRateLimit(twoSecondsInterval, getEasyConvertHistory),
GetOneClickRepayHistory: request.NewRateLimit(twoSecondsInterval, getOneClickRepayHistory),
OneClickRepayCurrencyList: request.NewRateLimit(twoSecondsInterval, oneClickRepayCurrencyList),
TradeOneClickRepay: request.NewRateLimit(twoSecondsInterval, tradeOneClickRepay),
placeOrderEPL: request.NewRateLimitWithWeight(twoSecondsInterval, placeOrderRate, 1),
placeMultipleOrdersEPL: request.NewRateLimitWithWeight(twoSecondsInterval, placeMultipleOrdersRate, 1),
cancelOrderEPL: request.NewRateLimitWithWeight(twoSecondsInterval, cancelOrderRate, 1),
cancelMultipleOrdersEPL: request.NewRateLimitWithWeight(twoSecondsInterval, cancelMultipleOrdersRate, 1),
amendOrderEPL: request.NewRateLimitWithWeight(twoSecondsInterval, amendOrderRate, 1),
amendMultipleOrdersEPL: request.NewRateLimitWithWeight(twoSecondsInterval, amendMultipleOrdersRate, 1),
closePositionEPL: request.NewRateLimitWithWeight(twoSecondsInterval, closePositionsRate, 1),
getOrderDetEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getOrderDetails, 1),
getOrderListEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getOrderListRate, 1),
getOrderHistory7DaysEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getOrderHistory7DaysRate, 1),
getOrderHistory3MonthsEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getOrderHistory3MonthsRate, 1),
getTransactionDetail3DaysEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getTransactionDetail3DaysRate, 1),
getTransactionDetail3MonthsEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getTransactionDetail3MonthsRate, 1),
placeAlgoOrderEPL: request.NewRateLimitWithWeight(twoSecondsInterval, placeAlgoOrderRate, 1),
cancelAlgoOrderEPL: request.NewRateLimitWithWeight(twoSecondsInterval, cancelAlgoOrderRate, 1),
cancelAdvanceAlgoOrderEPL: request.NewRateLimitWithWeight(twoSecondsInterval, cancelAdvanceAlgoOrderRate, 1),
getAlgoOrderListEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getAlgoOrderListRate, 1),
getAlgoOrderHistoryEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getAlgoOrderHistoryRate, 1),
getEasyConvertCurrencyListEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getEasyConvertCurrencyListRate, 1),
placeEasyConvertEPL: request.NewRateLimitWithWeight(twoSecondsInterval, placeEasyConvert, 1),
getEasyConvertHistoryEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getEasyConvertHistory, 1),
getOneClickRepayHistoryEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getOneClickRepayHistory, 1),
oneClickRepayCurrencyListEPL: request.NewRateLimitWithWeight(twoSecondsInterval, oneClickRepayCurrencyList, 1),
tradeOneClickRepayEPL: request.NewRateLimitWithWeight(twoSecondsInterval, tradeOneClickRepay, 1),
// Block Trading endpoints
GetCounterparties: request.NewRateLimit(twoSecondsInterval, getCounterpartiesRate),
CreateRfq: request.NewRateLimit(twoSecondsInterval, createRfqRate),
CancelRfq: request.NewRateLimit(twoSecondsInterval, cancelRfqRate),
CancelMultipleRfq: request.NewRateLimit(twoSecondsInterval, cancelMultipleRfqRate),
CancelAllRfqs: request.NewRateLimit(twoSecondsInterval, cancelAllRfqsRate),
ExecuteQuote: request.NewRateLimit(threeSecondsInterval, executeQuoteRate),
SetQuoteProducts: request.NewRateLimit(twoSecondsInterval, setQuoteProducts),
RestMMPStatus: request.NewRateLimit(twoSecondsInterval, restMMPStatus),
CreateQuote: request.NewRateLimit(twoSecondsInterval, createQuoteRate),
CancelQuote: request.NewRateLimit(twoSecondsInterval, cancelQuoteRate),
CancelMultipleQuotes: request.NewRateLimit(twoSecondsInterval, cancelMultipleQuotesRate),
CancelAllQuotes: request.NewRateLimit(twoSecondsInterval, cancelAllQuotes),
GetRfqs: request.NewRateLimit(twoSecondsInterval, getRfqsRate),
GetQuotes: request.NewRateLimit(twoSecondsInterval, getQuotesRate),
GetTrades: request.NewRateLimit(twoSecondsInterval, getTradesRate),
GetTradesHistory: request.NewRateLimit(twoSecondsInterval, getTradesHistoryRate),
GetPublicTrades: request.NewRateLimit(twoSecondsInterval, getPublicTradesRate),
getCounterpartiesEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getCounterpartiesRate, 1),
createRfqEPL: request.NewRateLimitWithWeight(twoSecondsInterval, createRfqRate, 1),
cancelRfqEPL: request.NewRateLimitWithWeight(twoSecondsInterval, cancelRfqRate, 1),
cancelMultipleRfqEPL: request.NewRateLimitWithWeight(twoSecondsInterval, cancelMultipleRfqRate, 1),
cancelAllRfqsEPL: request.NewRateLimitWithWeight(twoSecondsInterval, cancelAllRfqsRate, 1),
executeQuoteEPL: request.NewRateLimitWithWeight(threeSecondsInterval, executeQuoteRate, 1),
setQuoteProductsEPL: request.NewRateLimitWithWeight(twoSecondsInterval, setQuoteProducts, 1),
restMMPStatusEPL: request.NewRateLimitWithWeight(twoSecondsInterval, restMMPStatus, 1),
createQuoteEPL: request.NewRateLimitWithWeight(twoSecondsInterval, createQuoteRate, 1),
cancelQuoteEPL: request.NewRateLimitWithWeight(twoSecondsInterval, cancelQuoteRate, 1),
cancelMultipleQuotesEPL: request.NewRateLimitWithWeight(twoSecondsInterval, cancelMultipleQuotesRate, 1),
cancelAllQuotesEPL: request.NewRateLimitWithWeight(twoSecondsInterval, cancelAllQuotes, 1),
getRfqsEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getRfqsRate, 1),
getQuotesEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getQuotesRate, 1),
getTradesEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getTradesRate, 1),
getTradesHistoryEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getTradesHistoryRate, 1),
getPublicTradesEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getPublicTradesRate, 1),
// Funding
GetCurrencies: request.NewRateLimit(oneSecondInterval, getCurrenciesRate),
GetBalance: request.NewRateLimit(oneSecondInterval, getBalanceRate),
GetAccountAssetValuation: request.NewRateLimit(twoSecondsInterval, getAccountAssetValuationRate),
FundsTransfer: request.NewRateLimit(oneSecondInterval, fundsTransferRate),
GetFundsTransferState: request.NewRateLimit(oneSecondInterval, getFundsTransferStateRate),
AssetBillsDetails: request.NewRateLimit(oneSecondInterval, assetBillsDetailsRate),
LightningDeposits: request.NewRateLimit(oneSecondInterval, lightningDepositsRate),
GetDepositAddress: request.NewRateLimit(oneSecondInterval, getDepositAddressRate),
GetDepositHistory: request.NewRateLimit(oneSecondInterval, getDepositHistoryRate),
Withdrawal: request.NewRateLimit(oneSecondInterval, withdrawalRate),
LightningWithdrawals: request.NewRateLimit(oneSecondInterval, lightningWithdrawalsRate),
CancelWithdrawal: request.NewRateLimit(oneSecondInterval, cancelWithdrawalRate),
GetWithdrawalHistory: request.NewRateLimit(oneSecondInterval, getWithdrawalHistoryRate),
SmallAssetsConvert: request.NewRateLimit(oneSecondInterval, smallAssetsConvertRate),
GetSavingBalance: request.NewRateLimit(oneSecondInterval, getSavingBalanceRate),
SavingsPurchaseRedempt: request.NewRateLimit(oneSecondInterval, savingsPurchaseRedemptionRate),
SetLendingRate: request.NewRateLimit(oneSecondInterval, setLendingRateRate),
GetLendingHistory: request.NewRateLimit(oneSecondInterval, getLendingHistoryRate),
GetPublicBorrowInfo: request.NewRateLimit(oneSecondInterval, getPublicBorrowInfoRate),
GetPublicBorrowHistory: request.NewRateLimit(oneSecondInterval, getPublicBorrowHistoryRate),
getCurrenciesEPL: request.NewRateLimitWithWeight(oneSecondInterval, getCurrenciesRate, 1),
getBalanceEPL: request.NewRateLimitWithWeight(oneSecondInterval, getBalanceRate, 1),
getAccountAssetValuationEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getAccountAssetValuationRate, 1),
fundsTransferEPL: request.NewRateLimitWithWeight(oneSecondInterval, fundsTransferRate, 1),
getFundsTransferStateEPL: request.NewRateLimitWithWeight(oneSecondInterval, getFundsTransferStateRate, 1),
assetBillsDetailsEPL: request.NewRateLimitWithWeight(oneSecondInterval, assetBillsDetailsRate, 1),
lightningDepositsEPL: request.NewRateLimitWithWeight(oneSecondInterval, lightningDepositsRate, 1),
getDepositAddressEPL: request.NewRateLimitWithWeight(oneSecondInterval, getDepositAddressRate, 1),
getDepositHistoryEPL: request.NewRateLimitWithWeight(oneSecondInterval, getDepositHistoryRate, 1),
withdrawalEPL: request.NewRateLimitWithWeight(oneSecondInterval, withdrawalRate, 1),
lightningWithdrawalsEPL: request.NewRateLimitWithWeight(oneSecondInterval, lightningWithdrawalsRate, 1),
cancelWithdrawalEPL: request.NewRateLimitWithWeight(oneSecondInterval, cancelWithdrawalRate, 1),
getWithdrawalHistoryEPL: request.NewRateLimitWithWeight(oneSecondInterval, getWithdrawalHistoryRate, 1),
smallAssetsConvertEPL: request.NewRateLimitWithWeight(oneSecondInterval, smallAssetsConvertRate, 1),
getSavingBalanceEPL: request.NewRateLimitWithWeight(oneSecondInterval, getSavingBalanceRate, 1),
savingsPurchaseRedemptionEPL: request.NewRateLimitWithWeight(oneSecondInterval, savingsPurchaseRedemptionRate, 1),
setLendingRateEPL: request.NewRateLimitWithWeight(oneSecondInterval, setLendingRateRate, 1),
getLendingHistoryEPL: request.NewRateLimitWithWeight(oneSecondInterval, getLendingHistoryRate, 1),
getPublicBorrowInfoEPL: request.NewRateLimitWithWeight(oneSecondInterval, getPublicBorrowInfoRate, 1),
getPublicBorrowHistoryEPL: request.NewRateLimitWithWeight(oneSecondInterval, getPublicBorrowHistoryRate, 1),
// Convert
GetConvertCurrencies: request.NewRateLimit(oneSecondInterval, getConvertCurrenciesRate),
GetConvertCurrencyPair: request.NewRateLimit(oneSecondInterval, getConvertCurrencyPairRate),
EstimateQuote: request.NewRateLimit(oneSecondInterval, estimateQuoteRate),
ConvertTrade: request.NewRateLimit(oneSecondInterval, convertTradeRate),
GetConvertHistory: request.NewRateLimit(oneSecondInterval, getConvertHistoryRate),
getConvertCurrenciesEPL: request.NewRateLimitWithWeight(oneSecondInterval, getConvertCurrenciesRate, 1),
getConvertCurrencyPairEPL: request.NewRateLimitWithWeight(oneSecondInterval, getConvertCurrencyPairRate, 1),
estimateQuoteEPL: request.NewRateLimitWithWeight(oneSecondInterval, estimateQuoteRate, 1),
convertTradeEPL: request.NewRateLimitWithWeight(oneSecondInterval, convertTradeRate, 1),
getConvertHistoryEPL: request.NewRateLimitWithWeight(oneSecondInterval, getConvertHistoryRate, 1),
// Account
GetAccountBalance: request.NewRateLimit(twoSecondsInterval, getAccountBalanceRate),
GetPositions: request.NewRateLimit(twoSecondsInterval, getPositionsRate),
GetPositionsHistory: request.NewRateLimit(tenSecondsInterval, getPositionsHistoryRate),
GetAccountAndPositionRisk: request.NewRateLimit(twoSecondsInterval, getAccountAndPositionRiskRate),
GetBillsDetails: request.NewRateLimit(oneSecondInterval, getBillsDetailsRate),
GetAccountConfiguration: request.NewRateLimit(twoSecondsInterval, getAccountConfigurationRate),
SetPositionMode: request.NewRateLimit(twoSecondsInterval, setPositionModeRate),
SetLeverage: request.NewRateLimit(twoSecondsInterval, setLeverageRate),
GetMaximumBuyOrSellAmount: request.NewRateLimit(twoSecondsInterval, getMaximumBuyOrSellAmountRate),
GetMaximumAvailableTradableAmount: request.NewRateLimit(twoSecondsInterval, getMaximumAvailableTradableAmountRate),
IncreaseOrDecreaseMargin: request.NewRateLimit(twoSecondsInterval, increaseOrDecreaseMarginRate),
GetLeverage: request.NewRateLimit(twoSecondsInterval, getLeverageRate),
GetTheMaximumLoanOfInstrument: request.NewRateLimit(twoSecondsInterval, getTheMaximumLoanOfInstrumentRate),
GetFeeRates: request.NewRateLimit(twoSecondsInterval, getFeeRatesRate),
GetInterestAccruedData: request.NewRateLimit(twoSecondsInterval, getInterestAccruedDataRate),
GetInterestRate: request.NewRateLimit(twoSecondsInterval, getInterestRateRate),
SetGreeks: request.NewRateLimit(twoSecondsInterval, setGreeksRate),
IsolatedMarginTradingSettings: request.NewRateLimit(twoSecondsInterval, isolatedMarginTradingSettingsRate),
GetMaximumWithdrawals: request.NewRateLimit(twoSecondsInterval, getMaximumWithdrawalsRate),
GetAccountRiskState: request.NewRateLimit(twoSecondsInterval, getAccountRiskStateRate),
VipLoansBorrowAnsRepay: request.NewRateLimit(oneSecondInterval, vipLoansBorrowAndRepayRate),
GetBorrowAnsRepayHistoryHistory: request.NewRateLimit(twoSecondsInterval, getBorrowAnsRepayHistoryHistoryRate),
GetBorrowInterestAndLimit: request.NewRateLimit(twoSecondsInterval, getBorrowInterestAndLimitRate),
PositionBuilder: request.NewRateLimit(twoSecondsInterval, positionBuilderRate),
GetGreeks: request.NewRateLimit(twoSecondsInterval, getGreeksRate),
GetPMLimitation: request.NewRateLimit(twoSecondsInterval, getPMLimitation),
getAccountBalanceEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getAccountBalanceRate, 1),
getPositionsEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getPositionsRate, 1),
getPositionsHistoryEPL: request.NewRateLimitWithWeight(tenSecondsInterval, getPositionsHistoryRate, 1),
getAccountAndPositionRiskEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getAccountAndPositionRiskRate, 1),
getBillsDetailsEPL: request.NewRateLimitWithWeight(oneSecondInterval, getBillsDetailsRate, 1),
getAccountConfigurationEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getAccountConfigurationRate, 1),
setPositionModeEPL: request.NewRateLimitWithWeight(twoSecondsInterval, setPositionModeRate, 1),
setLeverageEPL: request.NewRateLimitWithWeight(twoSecondsInterval, setLeverageRate, 1),
getMaximumBuyOrSellAmountEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getMaximumBuyOrSellAmountRate, 1),
getMaximumAvailableTradableAmountEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getMaximumAvailableTradableAmountRate, 1),
increaseOrDecreaseMarginEPL: request.NewRateLimitWithWeight(twoSecondsInterval, increaseOrDecreaseMarginRate, 1),
getLeverageEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getLeverageRate, 1),
getTheMaximumLoanOfInstrumentEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getTheMaximumLoanOfInstrumentRate, 1),
getFeeRatesEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getFeeRatesRate, 1),
getInterestAccruedDataEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getInterestAccruedDataRate, 1),
getInterestRateEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getInterestRateRate, 1),
setGreeksEPL: request.NewRateLimitWithWeight(twoSecondsInterval, setGreeksRate, 1),
isolatedMarginTradingSettingsEPL: request.NewRateLimitWithWeight(twoSecondsInterval, isolatedMarginTradingSettingsRate, 1),
getMaximumWithdrawalsEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getMaximumWithdrawalsRate, 1),
getAccountRiskStateEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getAccountRiskStateRate, 1),
vipLoansBorrowAnsRepayEPL: request.NewRateLimitWithWeight(oneSecondInterval, vipLoansBorrowAndRepayRate, 1),
getBorrowAnsRepayHistoryHistoryEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getBorrowAnsRepayHistoryHistoryRate, 1),
getBorrowInterestAndLimitEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getBorrowInterestAndLimitRate, 1),
positionBuilderEPL: request.NewRateLimitWithWeight(twoSecondsInterval, positionBuilderRate, 1),
getGreeksEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getGreeksRate, 1),
getPMLimitationEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getPMLimitation, 1),
// Sub Account Endpoints
ViewSubaccountList: request.NewRateLimit(twoSecondsInterval, viewSubaccountListRate),
ResetSubAccountAPIKey: request.NewRateLimit(oneSecondInterval, resetSubAccountAPIKey),
GetSubaccountTradingBalance: request.NewRateLimit(twoSecondsInterval, getSubaccountTradingBalanceRate),
GetSubaccountFundingBalance: request.NewRateLimit(twoSecondsInterval, getSubaccountFundingBalanceRate),
HistoryOfSubaccountTransfer: request.NewRateLimit(oneSecondInterval, historyOfSubaccountTransferRate),
MasterAccountsManageTransfersBetweenSubaccount: request.NewRateLimit(oneSecondInterval, masterAccountsManageTransfersBetweenSubaccountRate),
SetPermissionOfTransferOut: request.NewRateLimit(oneSecondInterval, setPermissionOfTransferOutRate),
GetCustodyTradingSubaccountList: request.NewRateLimit(oneSecondInterval, getCustodyTradingSubaccountListRate),
viewSubaccountListEPL: request.NewRateLimitWithWeight(twoSecondsInterval, viewSubaccountListRate, 1),
resetSubAccountAPIKeyEPL: request.NewRateLimitWithWeight(oneSecondInterval, resetSubAccountAPIKey, 1),
getSubaccountTradingBalanceEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getSubaccountTradingBalanceRate, 1),
getSubaccountFundingBalanceEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getSubaccountFundingBalanceRate, 1),
historyOfSubaccountTransferEPL: request.NewRateLimitWithWeight(oneSecondInterval, historyOfSubaccountTransferRate, 1),
masterAccountsManageTransfersBetweenSubaccountEPL: request.NewRateLimitWithWeight(oneSecondInterval, masterAccountsManageTransfersBetweenSubaccountRate, 1),
setPermissionOfTransferOutEPL: request.NewRateLimitWithWeight(oneSecondInterval, setPermissionOfTransferOutRate, 1),
getCustodyTradingSubaccountListEPL: request.NewRateLimitWithWeight(oneSecondInterval, getCustodyTradingSubaccountListRate, 1),
// Grid Trading Endpoints
GridTrading: request.NewRateLimit(twoSecondsInterval, gridTradingRate),
AmendGridAlgoOrder: request.NewRateLimit(twoSecondsInterval, amendGridAlgoOrderRate),
StopGridAlgoOrder: request.NewRateLimit(twoSecondsInterval, stopGridAlgoOrderRate),
GetGridAlgoOrderList: request.NewRateLimit(twoSecondsInterval, getGridAlgoOrderListRate),
GetGridAlgoOrderHistory: request.NewRateLimit(twoSecondsInterval, getGridAlgoOrderHistoryRate),
GetGridAlgoOrderDetails: request.NewRateLimit(twoSecondsInterval, getGridAlgoOrderDetailsRate),
GetGridAlgoSubOrders: request.NewRateLimit(twoSecondsInterval, getGridAlgoSubOrdersRate),
GetGridAlgoOrderPositions: request.NewRateLimit(twoSecondsInterval, getGridAlgoOrderPositionsRate),
SpotGridWithdrawIncome: request.NewRateLimit(twoSecondsInterval, spotGridWithdrawIncomeRate),
ComputeMarginBalance: request.NewRateLimit(twoSecondsInterval, computeMarginBalance),
AdjustMarginBalance: request.NewRateLimit(twoSecondsInterval, adjustMarginBalance),
GetGridAIParameter: request.NewRateLimit(twoSecondsInterval, getGridAIParameter),
gridTradingEPL: request.NewRateLimitWithWeight(twoSecondsInterval, gridTradingRate, 1),
amendGridAlgoOrderEPL: request.NewRateLimitWithWeight(twoSecondsInterval, amendGridAlgoOrderRate, 1),
stopGridAlgoOrderEPL: request.NewRateLimitWithWeight(twoSecondsInterval, stopGridAlgoOrderRate, 1),
getGridAlgoOrderListEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getGridAlgoOrderListRate, 1),
getGridAlgoOrderHistoryEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getGridAlgoOrderHistoryRate, 1),
getGridAlgoOrderDetailsEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getGridAlgoOrderDetailsRate, 1),
getGridAlgoSubOrdersEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getGridAlgoSubOrdersRate, 1),
getGridAlgoOrderPositionsEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getGridAlgoOrderPositionsRate, 1),
spotGridWithdrawIncomeEPL: request.NewRateLimitWithWeight(twoSecondsInterval, spotGridWithdrawIncomeRate, 1),
computeMarginBalanceEPL: request.NewRateLimitWithWeight(twoSecondsInterval, computeMarginBalance, 1),
adjustMarginBalanceEPL: request.NewRateLimitWithWeight(twoSecondsInterval, adjustMarginBalance, 1),
getGridAIParameterEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getGridAIParameter, 1),
// Earn
GetOffer: request.NewRateLimit(oneSecondInterval, getOffer),
Purchase: request.NewRateLimit(oneSecondInterval, purchase),
Redeem: request.NewRateLimit(oneSecondInterval, redeem),
CancelPurchaseOrRedemption: request.NewRateLimit(oneSecondInterval, cancelPurchaseOrRedemption),
GetEarnActiveOrders: request.NewRateLimit(oneSecondInterval, getEarnActiveOrders),
GetFundingOrderHistory: request.NewRateLimit(oneSecondInterval, getFundingOrderHistory),
getOfferEPL: request.NewRateLimitWithWeight(oneSecondInterval, getOffer, 1),
purchaseEPL: request.NewRateLimitWithWeight(oneSecondInterval, purchase, 1),
redeemEPL: request.NewRateLimitWithWeight(oneSecondInterval, redeem, 1),
cancelPurchaseOrRedemptionEPL: request.NewRateLimitWithWeight(oneSecondInterval, cancelPurchaseOrRedemption, 1),
getEarnActiveOrdersEPL: request.NewRateLimitWithWeight(oneSecondInterval, getEarnActiveOrders, 1),
getFundingOrderHistoryEPL: request.NewRateLimitWithWeight(oneSecondInterval, getFundingOrderHistory, 1),
// Market Data
GetTickers: request.NewRateLimit(twoSecondsInterval, getTickersRate),
GetIndexTickers: request.NewRateLimit(twoSecondsInterval, getIndexTickersRate),
GetOrderBook: request.NewRateLimit(twoSecondsInterval, getOrderBookRate),
GetCandlesticks: request.NewRateLimit(twoSecondsInterval, getCandlesticksRate),
GetCandlesticksHistory: request.NewRateLimit(twoSecondsInterval, getCandlesticksHistoryRate),
GetIndexCandlesticks: request.NewRateLimit(twoSecondsInterval, getIndexCandlesticksRate),
GetMarkPriceCandlesticks: request.NewRateLimit(twoSecondsInterval, getMarkPriceCandlesticksRate),
GetTradesRequest: request.NewRateLimit(twoSecondsInterval, getTradesRequestRate),
Get24HTotalVolume: request.NewRateLimit(twoSecondsInterval, get24HTotalVolumeRate),
GetOracle: request.NewRateLimit(fiveSecondsInterval, getOracleRate),
GetExchangeRateRequest: request.NewRateLimit(twoSecondsInterval, getExchangeRateRequestRate),
GetIndexComponents: request.NewRateLimit(twoSecondsInterval, getIndexComponentsRate),
GetBlockTickers: request.NewRateLimit(twoSecondsInterval, getBlockTickersRate),
GetBlockTrades: request.NewRateLimit(twoSecondsInterval, getBlockTradesRate),
getTickersEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getTickersRate, 1),
getIndexTickersEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getIndexTickersRate, 1),
getOrderBookEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getOrderBookRate, 1),
getCandlestickEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getCandlesticksRate, 1),
getCandlestickHistoryEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getCandlesticksHistoryRate, 1),
getIndexCandlestickEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getIndexCandlesticksRate, 1),
getTradesRequestEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getTradesRequestRate, 1),
get24HTotalVolumeEPL: request.NewRateLimitWithWeight(twoSecondsInterval, get24HTotalVolumeRate, 1),
getOracleEPL: request.NewRateLimitWithWeight(fiveSecondsInterval, getOracleRate, 1),
getExchangeRateRequestEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getExchangeRateRequestRate, 1),
getIndexComponentsEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getIndexComponentsRate, 1),
getBlockTickersEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getBlockTickersRate, 1),
getBlockTradesEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getBlockTradesRate, 1),
// Public Data Endpoints
GetInstruments: request.NewRateLimit(twoSecondsInterval, getInstrumentsRate),
GetDeliveryExerciseHistory: request.NewRateLimit(twoSecondsInterval, getDeliveryExerciseHistoryRate),
GetOpenInterest: request.NewRateLimit(twoSecondsInterval, getOpenInterestRate),
GetFunding: request.NewRateLimit(twoSecondsInterval, getFundingRate),
GetFundingRateHistory: request.NewRateLimit(twoSecondsInterval, getFundingRateHistoryRate),
GetLimitPrice: request.NewRateLimit(twoSecondsInterval, getLimitPriceRate),
GetOptionMarketDate: request.NewRateLimit(twoSecondsInterval, getOptionMarketDateRate),
GetEstimatedDeliveryExercisePrice: request.NewRateLimit(twoSecondsInterval, getEstimatedDeliveryExercisePriceRate),
GetDiscountRateAndInterestFreeQuota: request.NewRateLimit(twoSecondsInterval, getDiscountRateAndInterestFreeQuotaRate),
GetSystemTime: request.NewRateLimit(twoSecondsInterval, getSystemTimeRate),
GetLiquidationOrders: request.NewRateLimit(twoSecondsInterval, getLiquidationOrdersRate),
GetMarkPrice: request.NewRateLimit(twoSecondsInterval, getMarkPriceRate),
GetPositionTiers: request.NewRateLimit(twoSecondsInterval, getPositionTiersRate),
GetInterestRateAndLoanQuota: request.NewRateLimit(twoSecondsInterval, getInterestRateAndLoanQuotaRate),
GetInterestRateAndLoanQuoteForVIPLoans: request.NewRateLimit(twoSecondsInterval, getInterestRateAndLoanQuoteForVIPLoansRate),
GetUnderlying: request.NewRateLimit(twoSecondsInterval, getUnderlyingRate),
GetInsuranceFund: request.NewRateLimit(twoSecondsInterval, getInsuranceFundRate),
UnitConvert: request.NewRateLimit(twoSecondsInterval, unitConvertRate),
getInstrumentsEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getInstrumentsRate, 1),
getDeliveryExerciseHistoryEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getDeliveryExerciseHistoryRate, 1),
getOpenInterestEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getOpenInterestRate, 1),
getFundingEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getFundingRate, 1),
getFundingRateHistoryEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getFundingRateHistoryRate, 1),
getLimitPriceEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getLimitPriceRate, 1),
getOptionMarketDateEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getOptionMarketDateRate, 1),
getEstimatedDeliveryExercisePriceEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getEstimatedDeliveryExercisePriceRate, 1),
getDiscountRateAndInterestFreeQuotaEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getDiscountRateAndInterestFreeQuotaRate, 1),
getSystemTimeEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getSystemTimeRate, 1),
getLiquidationOrdersEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getLiquidationOrdersRate, 1),
getMarkPriceEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getMarkPriceRate, 1),
getPositionTiersEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getPositionTiersRate, 1),
getInterestRateAndLoanQuotaEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getInterestRateAndLoanQuotaRate, 1),
getInterestRateAndLoanQuoteForVIPLoansEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getInterestRateAndLoanQuoteForVIPLoansRate, 1),
getUnderlyingEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getUnderlyingRate, 1),
getInsuranceFundEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getInsuranceFundRate, 1),
unitConvertEPL: request.NewRateLimitWithWeight(twoSecondsInterval, unitConvertRate, 1),
// Trading Data Endpoints
GetSupportCoin: request.NewRateLimit(twoSecondsInterval, getSupportCoinRate),
GetTakerVolume: request.NewRateLimit(twoSecondsInterval, getTakerVolumeRate),
GetMarginLendingRatio: request.NewRateLimit(twoSecondsInterval, getMarginLendingRatioRate),
GetLongShortRatio: request.NewRateLimit(twoSecondsInterval, getLongShortRatioRate),
GetContractsOpenInterestAndVolume: request.NewRateLimit(twoSecondsInterval, getContractsOpenInterestAndVolumeRate),
GetOptionsOpenInterestAndVolume: request.NewRateLimit(twoSecondsInterval, getOptionsOpenInterestAndVolumeRate),
GetPutCallRatio: request.NewRateLimit(twoSecondsInterval, getPutCallRatioRate),
GetOpenInterestAndVolume: request.NewRateLimit(twoSecondsInterval, getOpenInterestAndVolumeRate),
GetTakerFlow: request.NewRateLimit(twoSecondsInterval, getTakerFlowRate),
getSupportCoinEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getSupportCoinRate, 1),
getTakerVolumeEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getTakerVolumeRate, 1),
getMarginLendingRatioEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getMarginLendingRatioRate, 1),
getLongShortRatioEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getLongShortRatioRate, 1),
getContractsOpenInterestAndVolumeEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getContractsOpenInterestAndVolumeRate, 1),
getOptionsOpenInterestAndVolumeEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getOptionsOpenInterestAndVolumeRate, 1),
getPutCallRatioEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getPutCallRatioRate, 1),
getOpenInterestAndVolumeEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getOpenInterestAndVolumeRate, 1),
getTakerFlowEPL: request.NewRateLimitWithWeight(twoSecondsInterval, getTakerFlowRate, 1),
// Status Endpoints
GetEventStatus: request.NewRateLimit(fiveSecondsInterval, getEventStatusRate),
getEventStatusEPL: request.NewRateLimitWithWeight(fiveSecondsInterval, getEventStatusRate, 1),
}
}

View File

@@ -934,7 +934,7 @@ func (p *Poloniex) SendHTTPRequest(ctx context.Context, ep exchange.URL, path st
HTTPRecording: p.HTTPRecording,
}
return p.SendPayload(ctx, request.Unset, func() (*request.Item, error) {
return p.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) {
return item, nil
}, request.UnauthenticatedRequest)
}
@@ -950,7 +950,7 @@ func (p *Poloniex) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange
return err
}
return p.SendPayload(ctx, request.Unset, func() (*request.Item, error) {
return p.SendPayload(ctx, request.Auth, func() (*request.Item, error) {
headers := make(map[string]string)
headers["Content-Type"] = "application/x-www-form-urlencoded"
headers["Key"] = creds.Key

View File

@@ -123,7 +123,7 @@ func (p *Poloniex) SetDefaults() {
p.Requester, err = request.New(p.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
request.WithLimiter(GetRateLimit()))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -1,11 +1,9 @@
package poloniex
import (
"context"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
const (
@@ -14,28 +12,14 @@ const (
poloniexUnauthRate = 6
)
// RateLimit implements the request.Limiter interface
type RateLimit struct {
Auth *rate.Limiter
UnAuth *rate.Limiter
}
// Limit limits outbound calls
func (r *RateLimit) Limit(ctx context.Context, f request.EndpointLimit) error {
if f == request.Auth {
return r.Auth.Wait(ctx)
}
return r.UnAuth.Wait(ctx)
}
// SetRateLimit returns the rate limit for the exchange
// GetRateLimit returns the rate limit for the exchange
// If your account's volume is over $5 million in 30 day volume,
// you may be eligible for an API rate limit increase.
// Please email poloniex@circle.com.
// As per https://docs.poloniex.com/#http-api
func SetRateLimit() *RateLimit {
return &RateLimit{
Auth: request.NewRateLimit(poloniexRateInterval, poloniexAuthRate),
UnAuth: request.NewRateLimit(poloniexRateInterval, poloniexUnauthRate),
func GetRateLimit() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
request.Auth: request.NewRateLimitWithWeight(poloniexRateInterval, poloniexAuthRate, 1),
request.UnAuth: request.NewRateLimitWithWeight(poloniexRateInterval, poloniexUnauthRate, 1),
}
}

View File

@@ -14,6 +14,10 @@ import (
var (
ErrRateLimiterAlreadyDisabled = errors.New("rate limiter already disabled")
ErrRateLimiterAlreadyEnabled = errors.New("rate limiter already enabled")
errLimiterSystemIsNil = errors.New("limiter system is nil")
errInvalidWeightCount = errors.New("invalid weight count must equal or greater than 1")
errSpecificRateLimiterIsNil = errors.New("specific rate limiter is nil")
)
// Const here define individual functionality sub types for rate limiting
@@ -23,26 +27,35 @@ const (
UnAuth
)
// BasicLimit denotes basic rate limit that implements the Limiter interface
// does not need to set endpoint functionality.
type BasicLimit struct {
r *rate.Limiter
}
// Limit executes a single rate limit set by NewRateLimit
func (b *BasicLimit) Limit(ctx context.Context, _ EndpointLimit) error {
return b.r.Wait(ctx)
}
// EndpointLimit defines individual endpoint rate limits that are set when
// New is called.
type EndpointLimit int
type EndpointLimit uint16
// Limiter interface groups rate limit functionality defined in the REST
// wrapper for extended rate limiting configuration i.e. Shells of rate
// limits with a global rate for sub rates.
type Limiter interface {
Limit(context.Context, EndpointLimit) error
// Weight defines the number of reservations to be used. This is a generalised
// weight for rate limiting. e.g. n weight = n request. i.e. 50 Weight = 50
// requests.
type Weight uint8
// RateLimitDefinitions is a map of endpoint limits to rate limiters
type RateLimitDefinitions map[interface{}]*RateLimiterWithWeight
// RateLimiterWithWeight is a rate limiter coupled with a weight count which
// refers to the number or weighting of the request. This is used to define
// the rate limit for a specific endpoint.
type RateLimiterWithWeight struct {
*rate.Limiter
Weight
}
// Reservations is a slice of rate reservations
type Reservations []*rate.Reservation
// CancelAll cancels all potential reservations to free up rate limiter for
// context cancellations and deadline exceeded cases.
func (r Reservations) CancelAll() {
for x := range r {
r[x].Cancel()
}
}
// NewRateLimit creates a new RateLimit based of time interval and how many
@@ -59,10 +72,25 @@ func NewRateLimit(interval time.Duration, actions int) *rate.Limiter {
return rate.NewLimiter(rate.Limit(rps), 1)
}
// NewRateLimitWithWeight creates a new RateLimit based of time interval and how
// many actions allowed. This also has a weight count which refers to the number
// or weighting of the request. This is used to define the rate limit for a
// specific endpoint.
func NewRateLimitWithWeight(interval time.Duration, actions int, weight Weight) *RateLimiterWithWeight {
return GetRateLimiterWithWeight(NewRateLimit(interval, actions), weight)
}
// GetRateLimiterWithWeight couples a rate limiter with a weight count into an
// accepted defined rate limiter with weight struct
func GetRateLimiterWithWeight(l *rate.Limiter, weight Weight) *RateLimiterWithWeight {
return &RateLimiterWithWeight{l, weight}
}
// NewBasicRateLimit returns an object that implements the limiter interface
// for basic rate limit
func NewBasicRateLimit(interval time.Duration, actions int) Limiter {
return &BasicLimit{NewRateLimit(interval, actions)}
func NewBasicRateLimit(interval time.Duration, actions int, weight Weight) RateLimitDefinitions {
rl := NewRateLimitWithWeight(interval, actions, weight)
return RateLimitDefinitions{Unset: rl, Auth: rl, UnAuth: rl}
}
// InitiateRateLimit sleeps for designated end point rate limits
@@ -73,12 +101,46 @@ func (r *Requester) InitiateRateLimit(ctx context.Context, e EndpointLimit) erro
if atomic.LoadInt32(&r.disableRateLimiter) == 1 {
return nil
}
if r.limiter != nil {
return r.limiter.Limit(ctx, e)
if r.limiter == nil {
return fmt.Errorf("cannot rate limit request %w", errLimiterSystemIsNil)
}
return nil
rateLimiter := r.limiter[e]
if rateLimiter == nil {
return fmt.Errorf("cannot rate limit request %w for endpoint %d", errSpecificRateLimiterIsNil, e)
}
if rateLimiter.Weight <= 0 {
return fmt.Errorf("cannot rate limit request %w for endpoint %d", errInvalidWeightCount, e)
}
var finalDelay time.Duration
var reservations = make(Reservations, rateLimiter.Weight)
for i := Weight(0); i < rateLimiter.Weight; i++ {
// Consume 1 weight at a time as this avoids needing burst capacity in the limiter,
// which would otherwise allow the rate limit to be exceeded over short periods
reservations[i] = rateLimiter.Reserve()
finalDelay = reservations[i].Delay()
}
if dl, ok := ctx.Deadline(); ok && dl.Before(time.Now().Add(finalDelay)) {
reservations.CancelAll()
return fmt.Errorf("rate limit delay of %s will exceed deadline: %w",
finalDelay,
context.DeadlineExceeded)
}
tick := time.NewTimer(finalDelay)
select {
case <-tick.C:
return nil
case <-ctx.Done():
tick.Stop()
reservations.CancelAll()
return ctx.Err()
}
// TODO: Shutdown case
}
// DisableRateLimiter disables the rate limiting system for the exchange

View File

@@ -8,9 +8,9 @@ func WithBackoff(b Backoff) RequesterOption {
}
// WithLimiter configures the rate limiter for a Requester.
func WithLimiter(l Limiter) RequesterOption {
func WithLimiter(def RateLimitDefinitions) RequesterOption {
return func(r *Requester) {
r.limiter = l
r.limiter = def
}
}

View File

@@ -149,10 +149,12 @@ func (r *Requester) doRequest(ctx context.Context, endpoint EndpointLimit, newRe
default:
}
// Initiate a rate limit reservation and sleep on requested endpoint
err := r.InitiateRateLimit(ctx, endpoint)
if err != nil {
return fmt.Errorf("failed to rate limit HTTP request: %w", err)
if r.limiter != nil {
// Initiate a rate limit reservation and sleep on requested endpoint
err := r.InitiateRateLimit(ctx, endpoint)
if err != nil {
return fmt.Errorf("failed to rate limit HTTP request: %w", err)
}
}
p, err := newRequest()
@@ -231,7 +233,15 @@ func (r *Requester) doRequest(ctx context.Context, endpoint EndpointLimit, newRe
log.Errorf(log.RequestSys, "%s request has failed. Retrying request in %s, attempt %d", r.name, delay, attempt)
}
time.Sleep(delay)
if delay > 0 {
// Allow for context cancellation while delaying the retry.
select {
case <-time.After(delay):
case <-ctx.Done():
return ctx.Err()
}
}
continue
}

View File

@@ -3,7 +3,6 @@ package request
import (
"context"
"errors"
"fmt"
"io"
"log"
"math"
@@ -28,12 +27,12 @@ import (
const unexpected = "unexpected values"
var testURL string
var serverLimit *rate.Limiter
var serverLimit *RateLimiterWithWeight
func TestMain(m *testing.M) {
serverLimitInterval := time.Millisecond * 500
serverLimit = NewRateLimit(serverLimitInterval, 1)
serverLimitRetry := NewRateLimit(serverLimitInterval, 1)
serverLimit = NewRateLimitWithWeight(serverLimitInterval, 1, 1)
serverLimitRetry := NewRateLimitWithWeight(serverLimitInterval, 1, 1)
sm := http.NewServeMux()
sm.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "application/json")
@@ -102,26 +101,26 @@ func TestMain(m *testing.M) {
os.Exit(issues)
}
func TestNewRateLimit(t *testing.T) {
func TestNewRateLimitWithWeight(t *testing.T) {
t.Parallel()
r := NewRateLimit(time.Second*10, 5)
r := NewRateLimitWithWeight(time.Second*10, 5, 1)
if r.Limit() != 0.5 {
t.Fatal(unexpected)
}
// Ensures rate limiting factor is the same
r = NewRateLimit(time.Second*2, 1)
r = NewRateLimitWithWeight(time.Second*2, 1, 1)
if r.Limit() != 0.5 {
t.Fatal(unexpected)
}
// Test for open rate limit
r = NewRateLimit(time.Second*2, 0)
r = NewRateLimitWithWeight(time.Second*2, 0, 1)
if r.Limit() != rate.Inf {
t.Fatal(unexpected)
}
r = NewRateLimit(0, 69)
r = NewRateLimitWithWeight(0, 69, 1)
if r.Limit() != rate.Inf {
t.Fatal(unexpected)
}
@@ -201,39 +200,13 @@ func TestCheckRequest(t *testing.T) {
}
}
type GlobalLimitTest struct {
Auth *rate.Limiter
UnAuth *rate.Limiter
}
var errEndpointLimitNotFound = errors.New("endpoint limit not found")
func (g *GlobalLimitTest) Limit(ctx context.Context, e EndpointLimit) error {
switch e {
case Auth:
if g.Auth == nil {
return errors.New("auth rate not set")
}
return g.Auth.Wait(ctx)
case UnAuth:
if g.UnAuth == nil {
return errors.New("unauth rate not set")
}
return g.UnAuth.Wait(ctx)
default:
return fmt.Errorf("cannot execute functionality: %d %w",
e,
errEndpointLimitNotFound)
}
}
var globalshell = GlobalLimitTest{
Auth: NewRateLimit(time.Millisecond*600, 1),
UnAuth: NewRateLimit(time.Second*1, 100)}
var globalshell = RateLimitDefinitions{
Auth: NewRateLimitWithWeight(time.Millisecond*600, 1, 1),
UnAuth: NewRateLimitWithWeight(time.Second*1, 100, 1)}
func TestDoRequest(t *testing.T) {
t.Parallel()
r, err := New("test", new(http.Client), WithLimiter(&globalshell))
r, err := New("test", new(http.Client), WithLimiter(globalshell))
if err != nil {
t.Fatal(err)
}
@@ -270,13 +243,9 @@ func TestDoRequest(t *testing.T) {
}
// Invalid/missing endpoint limit
err = r.SendPayload(ctx, Unset, func() (*Item, error) {
return &Item{
Path: testURL,
}, nil
}, UnauthenticatedRequest)
if !errors.Is(err, errEndpointLimitNotFound) {
t.Fatalf("expected: %v but received: %v", errEndpointLimitNotFound, err)
err = r.SendPayload(ctx, Unset, func() (*Item, error) { return &Item{Path: testURL}, nil }, UnauthenticatedRequest)
if !errors.Is(err, errSpecificRateLimiterIsNil) {
t.Fatalf("expected: %v but received: %v", errSpecificRateLimiterIsNil, err)
}
// Force debug
@@ -497,7 +466,7 @@ func TestDoRequest_NotRetryable(t *testing.T) {
func TestGetNonce(t *testing.T) {
t.Parallel()
r, err := New("test", new(http.Client), WithLimiter(&globalshell))
r, err := New("test", new(http.Client), WithLimiter(globalshell))
require.NoError(t, err)
n1 := r.GetNonce(nonce.Unix)
assert.NotZero(t, n1)
@@ -505,7 +474,7 @@ func TestGetNonce(t *testing.T) {
assert.NotZero(t, n2)
assert.NotEqual(t, n1, n2)
r2, err := New("test", new(http.Client), WithLimiter(&globalshell))
r2, err := New("test", new(http.Client), WithLimiter(globalshell))
require.NoError(t, err)
n3 := r2.GetNonce(nonce.UnixNano)
assert.NotZero(t, n3)
@@ -520,7 +489,7 @@ func TestGetNonce(t *testing.T) {
// 40532461 30.29 ns/op 0 B/op 0 allocs/op (prev)
// 45329203 26.53 ns/op 0 B/op 0 allocs/op
func BenchmarkGetNonce(b *testing.B) {
r, err := New("test", new(http.Client), WithLimiter(&globalshell))
r, err := New("test", new(http.Client), WithLimiter(globalshell))
require.NoError(b, err)
b.ResetTimer()
for i := 0; i < b.N; i++ {
@@ -536,9 +505,7 @@ func TestSetProxy(t *testing.T) {
if !errors.Is(err, ErrRequestSystemIsNil) {
t.Fatalf("received: '%v', but expected: '%v'", err, ErrRequestSystemIsNil)
}
r, err = New("test",
&http.Client{Transport: new(http.Transport)},
WithLimiter(&globalshell))
r, err = New("test", &http.Client{Transport: new(http.Transport)}, WithLimiter(globalshell))
if err != nil {
t.Fatal(err)
}
@@ -561,16 +528,11 @@ func TestSetProxy(t *testing.T) {
}
func TestBasicLimiter(t *testing.T) {
r, err := New("test",
new(http.Client),
WithLimiter(NewBasicRateLimit(time.Second, 1)))
r, err := New("test", new(http.Client), WithLimiter(NewBasicRateLimit(time.Second, 1, 1)))
if err != nil {
t.Fatal(err)
}
i := Item{
Path: "http://www.google.com",
Method: http.MethodGet,
}
i := Item{Path: "http://www.google.com", Method: http.MethodGet}
ctx := context.Background()
tn := time.Now()
@@ -595,9 +557,7 @@ func TestBasicLimiter(t *testing.T) {
}
func TestEnableDisableRateLimit(t *testing.T) {
r, err := New("TestRequest",
new(http.Client),
WithLimiter(NewBasicRateLimit(time.Minute, 1)))
r, err := New("TestRequest", new(http.Client), WithLimiter(NewBasicRateLimit(time.Minute, 1, 1)))
if err != nil {
t.Fatal(err)
}

View File

@@ -27,7 +27,7 @@ var (
// Requester struct for the request client
type Requester struct {
_HTTPClient *client
limiter Limiter
limiter RateLimitDefinitions
reporter Reporter
name string
userAgent string

View File

@@ -77,7 +77,7 @@ func (y *Yobit) SetDefaults() {
y.Requester, err = request.New(y.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
// Server responses are cached every 2 seconds.
request.WithLimiter(request.NewBasicRateLimit(time.Second, 1)))
request.WithLimiter(request.NewBasicRateLimit(time.Second, 1, 1)))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}