Files
gocryptotrader/exchanges/bybit/ratelimit.go
Samuael A fb6d12ac69 exchanges: Update Bybit exchange to V5 (#1301)
* Adding Bybit public endpoints

* Completed adding market endpoints

* Added trade endpoints

* Adding position endpoints

* completing position endpoints

* Adding Pre-upgrade endpoints

* Completed adding Pre-upgrade and Account endpoints

* Added asset endpoints

* Added user endpoints and unit tests

* Adding spot leverage and margin trade endpoints

* spot margin trade added

* added spot-margin-trade, institutional lending, c2c lending, and broker

* Adding wrapper funnctions

* Working on wrapper public methods

* Added wrapper functions and unit tests

* Added websocket support with unit tests

* Update websocket handlers and added rate-limiter

* wrapper function, websocket handlers, and linter issues fixe

* unit tests fixes and codespell correction

* Update documentation

* Minor websocket handling fix and URL consts merging

* types, unit test other updates

* Updated websocket and methods based on review

* Added GetFeeByType method with unit test and fixes

* add filter for Unified and Normal endpoints

* Mock recording and unit tests update

* minor linter issue fix

* websocket and rest tests and fix

* change asset types and wrapper methods update

* rm: forgotten panic message

* endpoints, websocket  and unit tests update

* Added and updated endpoints and unit test

* linter and spell fix

* unit test and orders update

* Update on endpoints, fields, config pairs and formating, and unit tests

* minor update on responses

* Fix unit test and types

* Unit tests, models, and wrapper issues fix and mock test recording

* rm print statement

* Fix issue, add FundingRate wrapper func, mock record

* minor type and unit test update

* Update on order handling and unit test

* Minor test

* Minor fix in wrapper

* unit tests update, recording, and documentation update

* Unit tests and minor wrapper function update

* minor unit test fix

* Added newly added endpoints, unit tests, and mock recording

* Rename GetInstruments -> GetInstrumentInfo

* doc update

* Minor unit tests update

* Minor unit test and wrapper update

* Fix linter issue

* Add unit test and minor updates

* Revert websocket error declaration

* Revert websocket error declaration

* Balace --> Balance

* Fix config issues

* Added next funding time minor fix

* Update GetLatestFundingRates and record mock test data

* Added LatestFundingRate time

* Fix test issue of TestAllExchangeWrappers

* config pairs update

* configtest spot pairs update

* Minor update on options UpdateOrderExecutionLimits wrapper func

* Linter issue fix and added new currency codes

* Added new currency codes

* Update bybit pairs in config_example

* config assets pair format update
2024-01-11 12:35:46 +11:00

357 lines
16 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
)
const (
defaultEPL request.EndpointLimit = iota
createOrderEPL
createSpotOrderEPL
amendOrderEPL
cancelOrderEPL
cancelSpotEPL
cancelAllEPL
cancelAllSpotEPL
createBatchOrderEPL
amendBatchOrderEPL
cancelBatchOrderEPL
getOrderEPL
getOrderHistoryEPL
getPositionListEPL
getExecutionListEPL
getPositionClosedPNLEPL
postPositionSetLeverageEPL
setPositionTPLSModeEPL
setPositionRiskLimitEPL
stopTradingPositionEPL
getAccountWalletBalanceEPL
getAccountFeeEPL
getAssetTransferQueryInfoEPL
getAssetTransferQueryTransferCoinListEPL
getAssetTransferCoinListEPL
getAssetInterTransferListEPL
getSubMemberListEPL
getAssetUniversalTransferListEPL
getAssetAccountCoinBalanceEPL
getAssetDepositRecordsEPL
getAssetDepositSubMemberRecordsEPL
getAssetDepositSubMemberAddressEPL
getWithdrawRecordsEPL
getAssetCoinInfoEPL
getExchangeOrderRecordEPL
interTransferEPL
saveTransferSubMemberEPL
universalTransferEPL
createWithdrawalEPL
cancelWithdrawalEPL
userCreateSubMemberEPL
userCreateSubAPIKeyEPL
userFrozenSubMemberEPL
userUpdateAPIEPL
userUpdateSubAPIEPL
userDeleteAPIEPL
userDeleteSubAPIEPL
userQuerySubMembersEPL
userQueryAPIEPL
getSpotLeverageTokenOrderRecordsEPL
spotLeverageTokenPurchaseEPL
spotLeverTokenRedeemEPL
getSpotCrossMarginTradeLoanInfoEPL
getSpotCrossMarginTradeAccountEPL
getSpotCrossMarginTradeOrdersEPL
getSpotCrossMarginTradeRepayHistoryEPL
spotCrossMarginTradeLoanEPL
spotCrossMarginTradeRepayEPL
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),
}
}