Files
gocryptotrader/exchanges/bybit/ratelimit.go
Ryan O'Hara-Reid 981a08af83 bybit: assortment of updates (#1192)
* bybit: cherry-pickable

* bybit: implement fee fetching v5

* bybit: update to use nullable type

* bybit: fix some tests

* bybit: spell check fix

* remove redunant asset dec, and rm output

* rm comment code

* linter: fixerinos woooo

* bybit: constrict rate limit on public spot to v5

* exchanges/bybit/limits: update (CHERRY PICK ME)

* glorious: nIIIIIIIIIIIIIIITS

* glorious: nits continued

* updated comment

* update even more

* RM LINE!

* glorious: nits

* Update exchanges/sharedtestvalues/sharedtestvalues.go

Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io>

* fix

---------

Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io>
Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io>
2023-06-16 12:27:34 +10:00

371 lines
15 KiB
Go

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
spotRequestRate = 120
futuresPublicInterval = time.Second
futuresRequestRate = 50
spotPrivateInterval = time.Second
spotPrivateRequestRate = 20
spotPrivateFeeRequestRate = 10
futuresInterval = time.Minute
futuresDefaultRateCount = 100
futuresOrderRate = 100
futuresOrderListRate = 600
futuresExecutionRate = 120
futuresPositionRateCount = 75
futuresPositionListRate = 120
futuresFundingRate = 120
futuresWalletRate = 120
futuresAccountRate = 600
usdcPerpetualPublicRate = 50
usdcPerpetualCancelAllRate = 1
usdcPerpetualPrivateRate = 5
usdcPerpetualInterval = time.Second
)
const (
publicSpotRate request.EndpointLimit = iota
publicFuturesRate
privateSpotRate
privateFeeRate
cFuturesDefaultRate
cFuturesCancelActiveOrderRate
cFuturesCancelAllActiveOrderRate
cFuturesCreateConditionalOrderRate
cFuturesCancelConditionalOrderRate
cFuturesReplaceActiveOrderRate
cFuturesReplaceConditionalOrderRate
cFuturesCreateOrderRate
cFuturesCancelAllConditionalOrderRate
cFuturesGetActiveOrderRate
cFuturesGetConditionalOrderRate
cFuturesGetRealtimeOrderRate
cFuturesTradeRate
cFuturesSetLeverageRate
cFuturesUpdateMarginRate
cFuturesSetTradingRate
cFuturesSwitchPositionRate
cFuturesGetTradingFeeRate
cFuturesPositionRate
cFuturesWalletBalanceRate
cFuturesLastFundingFeeRate
cFuturesPredictFundingRate
cFuturesWalletFundRecordRate
cFuturesWalletWithdrawalRate
cFuturesAPIKeyInfoRate
uFuturesDefaultRate
uFuturesCreateOrderRate
uFuturesCancelOrderRate
uFuturesCancelAllOrderRate
uFuturesCreateConditionalOrderRate
uFuturesCancelConditionalOrderRate
uFuturesCancelAllConditionalOrderRate
uFuturesSetLeverageRate
uFuturesSwitchMargin
uFuturesSwitchPosition
uFuturesSetMarginRate
uFuturesSetTradingStopRate
uFuturesUpdateMarginRate
uFuturesPositionRate
uFuturesGetClosedTradesRate
uFuturesGetTradesRate
uFuturesGetActiveOrderRate
uFuturesGetActiveRealtimeOrderRate
uFuturesGetConditionalOrderRate
uFuturesGetConditionalRealtimeOrderRate
uFuturesGetMyLastFundingFeeRate
uFuturesPredictFundingRate
futuresDefaultRate
futuresCancelOrderRate
futuresCreateOrderRate
futuresReplaceOrderRate
futuresCancelAllOrderRate
futuresCancelAllConditionalOrderRate
futuresReplaceConditionalOrderRate
futuresCancelConditionalOrderRate
futuresCreateConditionalOrderRate
futuresGetActiveOrderRate
futuresGetConditionalOrderRate
futuresGetActiveRealtimeOrderRate
futuresGetConditionalRealtimeOrderRate
futuresGetTradeRate
futuresSetLeverageRate
futuresUpdateMarginRate
futuresSetTradingStopRate
futuresSwitchPositionModeRate
futuresSwitchMarginRate
futuresSwitchPositionRate
futuresPositionRate
usdcPublicRate
usdcCancelAllOrderRate
usdcPlaceOrderRate
usdcModifyOrderRate
usdcCancelOrderRate
usdcGetOrderRate
usdcGetOrderHistoryRate
usdcGetTradeHistoryRate
usdcGetTransactionRate
usdcGetWalletRate
usdcGetAssetRate
usdcGetMarginRate
usdcGetPositionRate
usdcSetLeverageRate
usdcGetSettlementRate
usdcSetRiskRate
usdcGetPredictedFundingRate
)
// RateLimit implements the request.Limiter interface
type RateLimit struct {
SpotRate *rate.Limiter
FuturesRate *rate.Limiter
PrivateSpotRate *rate.Limiter
PrivateFeeRate *rate.Limiter
CMFuturesDefaultRate *rate.Limiter
CMFuturesOrderRate *rate.Limiter
CMFuturesOrderListRate *rate.Limiter
CMFuturesExecutionRate *rate.Limiter
CMFuturesPositionRate *rate.Limiter
CMFuturesPositionListRate *rate.Limiter
CMFuturesFundingRate *rate.Limiter
CMFuturesWalletRate *rate.Limiter
CMFuturesAccountRate *rate.Limiter
UFuturesDefaultRate *rate.Limiter
UFuturesOrderRate *rate.Limiter
UFuturesPositionRate *rate.Limiter
UFuturesPositionListRate *rate.Limiter
UFuturesOrderListRate *rate.Limiter
UFuturesFundingRate *rate.Limiter
FuturesDefaultRate *rate.Limiter
FuturesOrderRate *rate.Limiter
FuturesOrderListRate *rate.Limiter
FuturesExecutionRate *rate.Limiter
FuturesPositionRate *rate.Limiter
FuturesPositionListRate *rate.Limiter
USDCPublic *rate.Limiter
USDCPlaceOrderRate *rate.Limiter
USDCModifyOrderRate *rate.Limiter
USDCCancelOrderRate *rate.Limiter
USDCCancelAllOrderRate *rate.Limiter
USDCGetOrderRate *rate.Limiter
USDCGetOrderHistoryRate *rate.Limiter
USDCGetTradeHistoryRate *rate.Limiter
USDCGetTransactionRate *rate.Limiter
USDCGetWalletRate *rate.Limiter
USDCGetAssetRate *rate.Limiter
USDCGetMarginRate *rate.Limiter
USDCGetPositionRate *rate.Limiter
USDCSetLeverageRate *rate.Limiter
USDCGetSettlementRate *rate.Limiter
USDCSetRiskRate *rate.Limiter
USDCGetPredictedFundingRate *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 publicSpotRate:
limiter, tokens = r.SpotRate, 1
case privateSpotRate:
limiter, tokens = r.PrivateSpotRate, 1
case privateFeeRate:
limiter, tokens = r.PrivateFeeRate, 1
case cFuturesDefaultRate:
limiter, tokens = r.CMFuturesDefaultRate, 1
case cFuturesCancelActiveOrderRate, cFuturesCreateConditionalOrderRate, cFuturesCancelConditionalOrderRate, cFuturesReplaceActiveOrderRate,
cFuturesReplaceConditionalOrderRate, cFuturesCreateOrderRate:
limiter, tokens = r.CMFuturesOrderRate, 1
case cFuturesCancelAllActiveOrderRate, cFuturesCancelAllConditionalOrderRate:
limiter, tokens = r.CMFuturesOrderRate, 10
case cFuturesGetActiveOrderRate, cFuturesGetConditionalOrderRate, cFuturesGetRealtimeOrderRate:
limiter, tokens = r.CMFuturesOrderListRate, 1
case cFuturesTradeRate:
limiter, tokens = r.CMFuturesExecutionRate, 1
case cFuturesSetLeverageRate, cFuturesUpdateMarginRate, cFuturesSetTradingRate, cFuturesSwitchPositionRate, cFuturesGetTradingFeeRate:
limiter, tokens = r.CMFuturesPositionRate, 1
case cFuturesPositionRate, cFuturesWalletBalanceRate:
limiter, tokens = r.CMFuturesPositionListRate, 1
case cFuturesLastFundingFeeRate, cFuturesPredictFundingRate:
limiter, tokens = r.CMFuturesFundingRate, 1
case cFuturesWalletFundRecordRate, cFuturesWalletWithdrawalRate:
limiter, tokens = r.CMFuturesWalletRate, 1
case cFuturesAPIKeyInfoRate:
limiter, tokens = r.CMFuturesAccountRate, 1
case uFuturesDefaultRate:
limiter, tokens = r.UFuturesDefaultRate, 1
case uFuturesCreateOrderRate, uFuturesCancelOrderRate, uFuturesCreateConditionalOrderRate, uFuturesCancelConditionalOrderRate:
limiter, tokens = r.UFuturesOrderRate, 1
case uFuturesCancelAllOrderRate, uFuturesCancelAllConditionalOrderRate:
limiter, tokens = r.UFuturesOrderRate, 10
case uFuturesSetLeverageRate, uFuturesSwitchMargin, uFuturesSwitchPosition, uFuturesSetMarginRate, uFuturesSetTradingStopRate, uFuturesUpdateMarginRate:
limiter, tokens = r.UFuturesPositionRate, 1
case uFuturesPositionRate, uFuturesGetClosedTradesRate, uFuturesGetTradesRate:
limiter, tokens = r.UFuturesPositionListRate, 1
case uFuturesGetActiveOrderRate, uFuturesGetActiveRealtimeOrderRate, uFuturesGetConditionalOrderRate, uFuturesGetConditionalRealtimeOrderRate:
limiter, tokens = r.UFuturesOrderListRate, 1
case uFuturesGetMyLastFundingFeeRate, uFuturesPredictFundingRate:
limiter, tokens = r.UFuturesFundingRate, 1
case futuresDefaultRate:
limiter, tokens = r.FuturesDefaultRate, 1
case futuresCancelOrderRate, futuresCreateOrderRate, futuresReplaceOrderRate, futuresReplaceConditionalOrderRate, futuresCancelConditionalOrderRate,
futuresCreateConditionalOrderRate:
limiter, tokens = r.FuturesOrderRate, 1
case futuresCancelAllOrderRate, futuresCancelAllConditionalOrderRate:
limiter, tokens = r.FuturesOrderRate, 10
case futuresGetActiveOrderRate, futuresGetConditionalOrderRate, futuresGetActiveRealtimeOrderRate, futuresGetConditionalRealtimeOrderRate:
limiter, tokens = r.FuturesOrderListRate, 1
case futuresGetTradeRate:
limiter, tokens = r.FuturesExecutionRate, 1
case futuresSetLeverageRate, futuresUpdateMarginRate, futuresSetTradingStopRate, futuresSwitchPositionModeRate, futuresSwitchMarginRate, futuresSwitchPositionRate:
limiter, tokens = r.FuturesPositionRate, 1
case futuresPositionRate:
limiter, tokens = r.FuturesPositionListRate, 1
case usdcPublicRate:
limiter, tokens = r.USDCPublic, 1
case usdcCancelAllOrderRate:
limiter, tokens = r.USDCCancelAllOrderRate, 1
case usdcPlaceOrderRate:
limiter, tokens = r.USDCPlaceOrderRate, 1
case usdcModifyOrderRate:
limiter, tokens = r.USDCModifyOrderRate, 1
case usdcCancelOrderRate:
limiter, tokens = r.USDCCancelOrderRate, 1
case usdcGetOrderRate:
limiter, tokens = r.USDCGetOrderRate, 1
case usdcGetOrderHistoryRate:
limiter, tokens = r.USDCGetOrderHistoryRate, 1
case usdcGetTradeHistoryRate:
limiter, tokens = r.USDCGetTradeHistoryRate, 1
case usdcGetTransactionRate:
limiter, tokens = r.USDCGetTransactionRate, 1
case usdcGetWalletRate:
limiter, tokens = r.USDCGetWalletRate, 1
case usdcGetAssetRate:
limiter, tokens = r.USDCGetAssetRate, 1
case usdcGetMarginRate:
limiter, tokens = r.USDCGetMarginRate, 1
case usdcGetPositionRate:
limiter, tokens = r.USDCGetPositionRate, 1
case usdcSetLeverageRate:
limiter, tokens = r.USDCSetLeverageRate, 1
case usdcGetSettlementRate:
limiter, tokens = r.USDCGetSettlementRate, 1
case usdcSetRiskRate:
limiter, tokens = r.USDCSetRiskRate, 1
case usdcGetPredictedFundingRate:
limiter, tokens = r.USDCGetPredictedFundingRate, 1
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, spotRequestRate),
FuturesRate: request.NewRateLimit(futuresPublicInterval, futuresRequestRate),
PrivateSpotRate: request.NewRateLimit(spotPrivateInterval, spotPrivateRequestRate),
PrivateFeeRate: request.NewRateLimit(spotPrivateInterval, spotPrivateFeeRequestRate),
CMFuturesDefaultRate: request.NewRateLimit(futuresInterval, futuresDefaultRateCount),
CMFuturesOrderRate: request.NewRateLimit(futuresInterval, futuresOrderRate),
CMFuturesOrderListRate: request.NewRateLimit(futuresInterval, futuresOrderListRate),
CMFuturesExecutionRate: request.NewRateLimit(futuresInterval, futuresExecutionRate),
CMFuturesPositionRate: request.NewRateLimit(futuresInterval, futuresPositionRateCount),
CMFuturesPositionListRate: request.NewRateLimit(futuresInterval, futuresPositionListRate),
CMFuturesFundingRate: request.NewRateLimit(futuresInterval, futuresFundingRate),
CMFuturesWalletRate: request.NewRateLimit(futuresInterval, futuresWalletRate),
CMFuturesAccountRate: request.NewRateLimit(futuresInterval, futuresAccountRate),
UFuturesDefaultRate: request.NewRateLimit(futuresInterval, futuresDefaultRateCount),
UFuturesOrderRate: request.NewRateLimit(futuresInterval, futuresOrderRate),
UFuturesPositionRate: request.NewRateLimit(futuresInterval, futuresPositionRateCount),
UFuturesPositionListRate: request.NewRateLimit(futuresInterval, futuresPositionListRate),
UFuturesOrderListRate: request.NewRateLimit(futuresInterval, futuresOrderListRate),
UFuturesFundingRate: request.NewRateLimit(futuresInterval, futuresFundingRate),
FuturesDefaultRate: request.NewRateLimit(futuresInterval, futuresDefaultRateCount),
FuturesOrderRate: request.NewRateLimit(futuresInterval, futuresOrderRate),
FuturesOrderListRate: request.NewRateLimit(futuresInterval, futuresOrderListRate),
FuturesExecutionRate: request.NewRateLimit(futuresInterval, futuresExecutionRate),
FuturesPositionRate: request.NewRateLimit(futuresInterval, futuresPositionRateCount),
FuturesPositionListRate: request.NewRateLimit(futuresInterval, futuresPositionListRate),
USDCPublic: request.NewRateLimit(usdcPerpetualInterval, usdcPerpetualPublicRate),
USDCPlaceOrderRate: request.NewRateLimit(usdcPerpetualInterval, usdcPerpetualPrivateRate),
USDCModifyOrderRate: request.NewRateLimit(usdcPerpetualInterval, usdcPerpetualPrivateRate),
USDCCancelOrderRate: request.NewRateLimit(usdcPerpetualInterval, usdcPerpetualPrivateRate),
USDCCancelAllOrderRate: request.NewRateLimit(usdcPerpetualInterval, usdcPerpetualCancelAllRate),
USDCGetOrderRate: request.NewRateLimit(usdcPerpetualInterval, usdcPerpetualPrivateRate),
USDCGetOrderHistoryRate: request.NewRateLimit(usdcPerpetualInterval, usdcPerpetualPrivateRate),
USDCGetTradeHistoryRate: request.NewRateLimit(usdcPerpetualInterval, usdcPerpetualPrivateRate),
USDCGetTransactionRate: request.NewRateLimit(usdcPerpetualInterval, usdcPerpetualPrivateRate),
USDCGetWalletRate: request.NewRateLimit(usdcPerpetualInterval, usdcPerpetualPrivateRate),
USDCGetAssetRate: request.NewRateLimit(usdcPerpetualInterval, usdcPerpetualPrivateRate),
USDCGetMarginRate: request.NewRateLimit(usdcPerpetualInterval, usdcPerpetualPrivateRate),
USDCGetPositionRate: request.NewRateLimit(usdcPerpetualInterval, usdcPerpetualPrivateRate),
USDCSetLeverageRate: request.NewRateLimit(usdcPerpetualInterval, usdcPerpetualPrivateRate),
USDCGetSettlementRate: request.NewRateLimit(usdcPerpetualInterval, usdcPerpetualPrivateRate),
USDCSetRiskRate: request.NewRateLimit(usdcPerpetualInterval, usdcPerpetualPrivateRate),
USDCGetPredictedFundingRate: request.NewRateLimit(usdcPerpetualInterval, usdcPerpetualPrivateRate),
}
}