跳转至内容

使用 API 限流器处理速率限制

注意

以下信息适用于构建直接集成到 Hummingbot 客户端的 spotperp 连接器的开发者。有关使用 Gateway 开发 gateway 连接器的信息,请参见 构建网关连接器

本节将详细介绍将 AsyncThrottler 集成到连接器中的必要步骤。AsyncThrottler 类使用异步上下文管理器来限制 API 和/或 WebSocket 请求,避免达到交易所服务器的速率限制。

提示

AsyncThrottler 集成到连接器中完全是可选的,但建议启用以提供更好的用户体验,并允许用户手动配置每个 Hummingbot 实例的可用速率限制。

RateLimit & LinkedLimitWeightPair 数据类

RateLimit 数据类用于表示交易所定义的速率限制,而 LinkedLimitWeightPair 数据类用于将端点消耗权重关联到其 API 池(如果未指定则默认为 1)

提示

limit_id 可以是任意分配的值。在接下来几节给出的示例中,分配给各种速率限制的 limit_id 要么是通用 API 池名称,要么是 API 端点的路径 url。

速率限制类型

在开始开发前识别交易所的速率限制实现方式非常重要。

AsyncThrottler 类可以处理几种类型的速率限制。以下部分将详细说明(并提供示例)如何为每种不同的速率限制类型初始化必要的 RateLimit 以及连接器和限流器之间的交互。

1. 每端点速率限制

注意

kucoin 是使用此速率限制实现的连接器示例。

这指的是在每个端点基础上应用的速率限制。对于这种速率限制类型,需要为每个端点检索的关键信息是其分配的 限制时间间隔。请注意,时间间隔是滚动计算的。例如,如果端点的速率限制是 20,时间间隔是 60,则意味着限流器将检查从当前时刻起过去 60 秒内是否已进行 20 次调用(到同一端点)。

配置速率限制

如上所述,需要从交易所检索的关键信息是每个端点的 limittime_interval(以秒为单位)。可以看到实现此功能的交易所示例在 kucoin 连接器中。

Kucoin 的速率限制可以在 这里 找到。

所有速率限制都在 kucoin_constants.py 文件中初始化。

RATE_LIMITS = [
    RateLimit(WS_CONNECTION_LIMIT_ID, limit=WS_CONNECTION_LIMIT, time_interval=WS_CONNECTION_TIME_INTERVAL),
    RateLimit(WS_REQUEST_LIMIT_ID, limit=100, time_interval=10),

    RateLimit(limit_id=PUBLIC_WS_DATA_PATH_URL, limit=NO_LIMIT, time_interval=1),
    RateLimit(limit_id=PRIVATE_WS_DATA_PATH_URL, limit=NO_LIMIT, time_interval=1),
    RateLimit(limit_id=TICKER_PRICE_CHANGE_PATH_URL, limit=NO_LIMIT, time_interval=1),
    RateLimit(limit_id=SYMBOLS_PATH_URL, limit=NO_LIMIT, time_interval=1),
    RateLimit(limit_id=SNAPSHOT_NO_AUTH_PATH_URL, limit=NO_LIMIT, time_interval=1),
    RateLimit(limit_id=ACCOUNTS_PATH_URL, limit=NO_LIMIT, time_interval=1),
    RateLimit(limit_id=SERVER_TIME_PATH_URL, limit=NO_LIMIT, time_interval=1),
    RateLimit(limit_id=GET_ORDER_LIMIT_ID, limit=NO_LIMIT, time_interval=1),
    RateLimit(limit_id=FEE_PATH_URL, limit=NO_LIMIT, time_interval=1),
    RateLimit(limit_id=ALL_TICKERS_PATH_URL, limit=NO_LIMIT, time_interval=1),
    RateLimit(limit_id=LIMIT_FILLS_PATH_URL, limit=NO_LIMIT, time_interval=1),
    RateLimit(limit_id=ORDER_CLIENT_ORDER_PATH_URL, limit=NO_LIMIT, time_interval=1),
    RateLimit(limit_id=POST_ORDER_LIMIT_ID, limit=45, time_interval=3),
    RateLimit(limit_id=DELETE_ORDER_LIMIT_ID, limit=60, time_interval=3),
    RateLimit(limit_id=ORDERS_PATH_URL, limit=45, time_interval=3),
    RateLimit(limit_id=FILLS_PATH_URL, limit=9, time_interval=3),
]

2. 速率限制池

注意

binancebinance_perpetualndax 是使用此速率限制实现的连接器示例

速率限制池指从单个速率限制中消耗的一组端点。对于这种速率限制类型,需要为每个端点检索的关键信息是其分配的池以及各自的限制和时间间隔。

配置速率限制

可以在 ndax 连接器中看到实现此功能的交易所示例。

所有速率限制都在 ndax_constants.py 文件中初始化。

# Pool IDs
HTTP_ENDPOINTS_LIMIT_ID = "AllHTTP"
WS_ENDPOINTS_LIMIT_ID = "AllWs"

RATE_LIMITS = [
  # REST API Pool(applies to all REST API endpoints)
  RateLimit(limit_id=HTTP_ENDPOINTS_LIMIT_ID, limit=HTTP_LIMIT, time_interval=MINUTE),
  # WebSocket Pool(applies to all WS requests)
  RateLimit(limit_id=WS_ENDPOINTS_LIMIT_ID, limit=WS_LIMIT, time_interval=MINUTE),
  # Public REST API endpoint
  RateLimit(
      limit_id=MARKETS_URL,
      limit=HTTP_LIMIT,
      time_interval=MINUTE,
      linked_limits=[LinkedLimitWeightPair(HTTP_ENDPOINTS_LIMIT_ID)],
  ),
  # WebSocket Auth endpoint
  RateLimit(
      limit_id=ACCOUNT_POSITION_EVENT_ENDPOINT_NAME,
      limit=WS_LIMIT,
      time_interval=MINUTE,
      linked_limits=[LinkedLimitWeightPair(WS_ENDPOINTS_LIMIT_ID)],
  ),
]

请注意,我们为 API 池分配一个任意的限制 ID(即HTTP_ENDPOINTS_LIMIT_ID),并使用LinkedLimitWeightPair将端点分配给 API 池。还需注意,一个端点可能属于多个其他端点。

还值得注意的是,API 池可能存在更复杂的实现,如bybit_perpetual连接器中的这里所示。

3. 加权请求速率限制

注意

binancebinance_perpetual是使用这种速率限制实现的连接器示例

对于加权速率限制,每个端点都被分配一个请求权重。通常,这些交易所会将速率限制池与请求权重结合使用,不同的端点会对给定池产生不同的影响。需要获取这些交易所的关键信息包括每个端点的权重、API 池的限制和时间间隔。

配置速率限制

可在binance连接器中看到实施此类速率限制的交易所示例。

Binance 的速率限制可在GET /api/v3/exchangeInfo端点的 API 响应中找到,这里有详细信息。

RATE_LIMITS = [
    # Pools
    RateLimit(limit_id=REQUEST_WEIGHT, limit=1200, time_interval=ONE_MINUTE),
    RateLimit(limit_id=ORDERS, limit=10, time_interval=ONE_SECOND),
    RateLimit(limit_id=ORDERS_24HR, limit=100000, time_interval=ONE_DAY),
    # Weighted Limits
    RateLimit(limit_id=SNAPSHOT_PATH_URL, limit=MAX_REQUEST, time_interval=ONE_MINUTE,
              linked_limits=[LinkedLimitWeightPair(REQUEST_WEIGHT, 50)]),
    RateLimit(limit_id=BINANCE_CREATE_ORDER, limit=MAX_REQUEST, time_interval=ONE_MINUTE,
              linked_limits=[LinkedLimitWeightPair(REQUEST_WEIGHT, 1),
                             LinkedLimitWeightPair(ORDERS, 1),
                             LinkedLimitWeightPair(ORDERS_24HR, 1)]),
]

Binance 同时实现了 API 池和加权请求。在上面的示例中,BINANCE_CREATE_ORDER端点对 3 个 API 池的请求权重为 1,而SNAPSHOT_PATH_URL端点对REQUEST_WEIGHT API 池的请求权重为 50。请注意,API 池有不同的速率限制和时间间隔。

将速率限制集成到连接器中

节流器应被所有发出服务器 API 调用且受交易所限制的相关类使用(无论是 HTTP 请求还是 WebSocket 请求)。即Exchange/DerivativeAPIOrderBookDataSourceUserStreamDataSource类。这样做可确保节流器管理由任何连接器组件发出的所有 REST API/WebSocket 请求。

使用节流器

节流器用作异步上下文管理器。

async with throttler.execute_task(path_url):
    res = await aiohttp.ClientSession().get(path_url)

警告

path_url必须与RATE_LIMITS常量中定义的端点limit_id匹配。节流器会将path_url与其分配的速率限制或 API 池进行匹配。