pkg/exchange: add rate limiter for query ticker, account

This commit is contained in:
Edwin 2023-11-01 11:46:43 +08:00
parent ec8ff03c89
commit 2cea089404
2 changed files with 58 additions and 12 deletions

View File

@ -10,7 +10,37 @@ import (
"github.com/c9s/bbgo/pkg/types"
)
func TestToGlobalMarket(t *testing.T) {
func Test_toGlobalBalance(t *testing.T) {
// sample:
// {
// "coinId":"10012",
// "coinName":"usdt",
// "available":"0",
// "frozen":"0",
// "lock":"0",
// "uTime":"1622697148"
// }
asset := bitgetapi.AccountAsset{
CoinId: 2,
CoinName: "USDT",
Available: fixedpoint.NewFromFloat(1.2),
Frozen: fixedpoint.NewFromFloat(0.5),
Lock: fixedpoint.NewFromFloat(0.5),
UTime: types.NewMillisecondTimestampFromInt(1622697148),
}
assert.Equal(t, types.Balance{
Currency: "USDT",
Available: fixedpoint.NewFromFloat(1.2),
Locked: fixedpoint.NewFromFloat(1), // frozen + lock
Borrowed: fixedpoint.Zero,
Interest: fixedpoint.Zero,
NetAsset: fixedpoint.Zero,
MaxWithdrawAmount: fixedpoint.Zero,
}, toGlobalBalance(asset))
}
func Test_toGlobalMarket(t *testing.T) {
// sample:
//{
// "symbol":"BTCUSDT_SPBL",

View File

@ -23,6 +23,10 @@ var log = logrus.WithFields(logrus.Fields{
var (
// queryMarketRateLimiter has its own rate limit. https://bitgetlimited.github.io/apidoc/en/spot/#get-symbols
queryMarketRateLimiter = rate.NewLimiter(rate.Every(time.Second/10), 5)
// queryAccountRateLimiter has its own rate limit. https://bitgetlimited.github.io/apidoc/en/spot/#get-account-assets
queryAccountRateLimiter = rate.NewLimiter(rate.Every(time.Second/5), 5)
// queryTickerRateLimiter has its own rate limit. https://bitgetlimited.github.io/apidoc/en/spot/#get-single-ticker
queryTickerRateLimiter = rate.NewLimiter(rate.Every(time.Second/10), 5)
)
type Exchange struct {
@ -80,11 +84,15 @@ func (e *Exchange) QueryMarkets(ctx context.Context) (types.MarketMap, error) {
}
func (e *Exchange) QueryTicker(ctx context.Context, symbol string) (*types.Ticker, error) {
if err := queryTickerRateLimiter.Wait(ctx); err != nil {
return nil, fmt.Errorf("ticker rate limiter wait error: %w", err)
}
req := e.client.NewGetTickerRequest()
req.Symbol(symbol)
ticker, err := req.Do(ctx)
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to query ticker: %w", err)
}
return &types.Ticker{
@ -110,26 +118,34 @@ func (e *Exchange) QueryKLines(ctx context.Context, symbol string, interval type
}
func (e *Exchange) QueryAccount(ctx context.Context) (*types.Account, error) {
req := e.client.NewGetAccountAssetsRequest()
resp, err := req.Do(ctx)
bals, err := e.QueryAccountBalances(ctx)
if err != nil {
return nil, err
}
bals := types.BalanceMap{}
for _, asset := range resp {
b := toGlobalBalance(asset)
bals[asset.CoinName] = b
}
account := types.NewAccount()
account.UpdateBalances(bals)
return account, nil
}
func (e *Exchange) QueryAccountBalances(ctx context.Context) (types.BalanceMap, error) {
// TODO implement me
panic("implement me")
if err := queryAccountRateLimiter.Wait(ctx); err != nil {
return nil, fmt.Errorf("account rate limiter wait error: %w", err)
}
req := e.client.NewGetAccountAssetsRequest()
resp, err := req.Do(ctx)
if err != nil {
return nil, fmt.Errorf("failed to query account assets: %w", err)
}
bals := types.BalanceMap{}
for _, asset := range resp {
b := toGlobalBalance(asset)
bals[asset.CoinName] = b
}
return bals, nil
}
func (e *Exchange) SubmitOrder(ctx context.Context, order types.SubmitOrder) (createdOrder *types.Order, err error) {