使用 API 限流器处理速率限制
注意
以下信息适用于开发直接集成到 Hummingbot 客户端的 spot 和 perp 连接器的开发者。有关使用 Gateway 开发 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 次调用。
配置速率限制
如上所述,需要从交易所获取的关键信息是每个端点的 limit(限制数)和 time_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. 速率限制池¶
注意
binance、binance_perpetual 和 ndax 是使用此类速率限制实现的连接器示例
速率限制池指的是共享同一速率限制的一组端点。对于此类速率限制类型,需要为每个端点获取的关键信息是其分配的池(或多个池)以及相应的限制和时间间隔。
配置速率限制
实现此机制的交易所示例可参见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. 加权请求速率限制¶
注意
binance和binance_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/Derivative、APIOrderBookDataSource和UserStreamDataSource类。这样做可确保节流器管理由连接器任何组件发出的所有 REST API/WebSocket 请求。
使用节流器¶
节流器作为异步上下文管理器使用。
警告
path_url必须与在RATE_LIMITS常量中定义的端点limit_id相匹配。节流器会将path_url与其分配的速率限制或 API 池进行匹配。