跳转到内容

小周期 K 线限频违规

小周期历史 K 线最容易触发限频。30 秒及以下的 bar 请求不要高频循环发送,否则 TWS 可能返回 pacing violation,并影响接下来一段时间的历史数据请求。

官方参考:Historical Data Limitations

规则中文解释
15 秒内不要发送完全相同的历史数据请求相同合约、周期、时长和数据类型重复请求会被限制。
2 秒内不要对同一合约、交易所和 tick 类型发送 6 次或更多请求高频批量请求会触发限制。
10 分钟内不要超过 60 次历史数据请求批量回补时必须排队。
BID_ASK 请求按两次计数买卖价历史数据消耗更快。

这些限制不能靠换 clientId 或多开脚本绕过。正确做法是排队、缓存和增量更新。

import time
def request_with_pacing(app, requests):
for req in requests:
app.reqHistoricalData(*req)
# 示例只演示基本间隔;批量程序还要统计 10 分钟窗口。
time.sleep(10)

正式程序应做请求队列,记录过去 10 分钟请求数量,并避免重复请求同一个窗口。

cache_key = (
contract.conId,
endDateTime,
durationStr,
barSizeSetting,
whatToShow,
useRTH,
formatDate,
)

如果同一个 cache_key 在 15 秒内已经请求过,应该使用缓存或等待,而不是再发一次。

字段用途
created_at记录请求加入队列时间。
sent_at记录实际发送时间。
contract_key合约唯一标识,优先使用 conId
barSizeSetting判断是否属于小周期请求。
whatToShowBID_ASK 要按更高成本计算。
statuspendingsentfinishedfailed
errorCode记录是否触发限频、权限或参数错误。
检查项说明
最近 15 秒是否重复同一请求重复请求最容易被忽略。
2 秒内是否对同一合约发送太多请求多线程下载容易触发。
10 分钟内请求数是否过高批量补数必须统计窗口。
是否请求 BID_ASK这类请求消耗更快。
是否把空结果当失败无限重试空结果可能是数据不可用,不要立刻重试。

看到 pacing violation 时,先打印最近请求队列,再判断是否需要放慢节奏、合并窗口或读取缓存。