行情接口的请求频率,很多时候要到数据量上来之后才会真正受到关注。查询一两只股票时,程序连续发几个请求通常没什么感觉;如果同时处理多只标的,再加上历史数据查询、行情刷新等任务,请求可能在很短时间内集中发送。
我处理这类程序时,会把请求间隔作为独立参数配置,而不是直接写在业务逻辑里。这样做的好处是比较直观:数据量变化了,可以调整频率;接口规则变化了,也不用重新修改整段程序。
设置间隔前,需要知道接口本身的频率限制。假设某个接口规定每分钟最多处理60次请求,在单任务情况下,可以简单理解为平均每秒一次。但如果程序同时运行10个任务,每个任务都按照每秒一次执行,整体请求量就会明显增加。
所以实际计算时,需要把 单任务频率、并发数量和请求类型放在一起看。历史数据和实时行情的需求也不一样,没有必要使用同一种请求节奏。
| 数据场景 | 常见方式 | 处理思路 |
|---|---|---|
| 实时Tick | WebSocket | 保持连接接收数据 |
| 实时行情 | WebSocket/HTTP | 根据更新频率选择 |
| 分钟K线 | HTTP | 控制固定请求间隔 |
| 历史数据 | HTTP | 分批获取 |
| 多标的数据 | HTTP | 限制并发数量 |
对于美股api来说,请求速度和数据更新速度并不完全是一回事。程序发送更多请求,并不意味着一定能够得到更多有价值的数据。
比较基础的做法是在两次请求之间增加等待时间。例如完成一次请求后暂停1秒,再执行下一次。这种方式容易实现,也适合数据量不大的程序。
实际写代码时,我更倾向于把间隔单独设置出来,并给等待时间增加少量变化。以 AllTick API 为例,下面用 Python 展示一种基础写法:
import time
import random
import requests
API_URL = "https://api.alltick.co/stock/quote"
REQUEST_INTERVAL = 1.5
def get_quote(symbol):
try:
response = requests.get(
API_URL,
params={"symbol": symbol},
timeout=10
)
response.raise_for_status()
return response.json()
except requests.RequestException as e:
print("请求失败:", e)
return None
symbols = ["MSFT", "NVDA", "AMZN", "META"]
for symbol in symbols:
data = get_quote(symbol)
if data:
print(symbol, data)
delay = REQUEST_INTERVAL + random.uniform(0, 0.5)
time.sleep(delay)
这里的
1.5 只是示例参数,并不是所有接口都适合这个数值。具体应该根据接口公开的频率规则、程序并发量以及实际数据需求进行调整。
如果一次只请求一只股票,增加等待时间比较容易处理。批量拉取历史数据就不同了,程序可能同时创建很多任务,即使每个任务内部都有等待时间,短时间内产生的请求仍然可能比较集中。
这种情况下,可以限制同时执行的任务数量。例如一次处理几个请求,完成后再继续下一批。历史数据还可以按照日期、时间范围进行拆分,避免单次任务处理过大的数据量。
已经获取的数据也可以保存到本地。对于不会频繁变化的历史行情,没有必要每次运行程序都重新请求一遍。缓存数据之后,既减少了接口调用,也能缩短后续分析的等待时间。
如果接口已经返回频率限制相关的响应,不建议立即重复发送相同请求。短时间连续重试不仅没有必要,还可能继续增加请求量。
比较常见的处理方式是逐步增加等待时间:
import time
def retry_request(request_func, max_retry=3):
for attempt in range(max_retry):
result = request_func()
if result is not None:
return result
wait_time = 2 ** attempt
print(f"等待 {wait_time} 秒后重试")
time.sleep(wait_time)
return None
这里采用的是递增等待策略。第一次等待时间较短,后续失败后逐步增加。实际项目中,如果接口返回了明确的等待时间,应当优先按照接口给出的规则处理。
还有一个容易混在一起的问题:实时行情不一定适合通过不断缩短HTTP间隔来获取。
如果程序需要持续接收Tick数据,可以使用WebSocket保持连接,由数据源持续推送新的消息。程序需要关注的是消息接收、解析和存储,而不是不断重新建立请求。
历史数据则可以采用批量HTTP请求,并通过请求间隔、并发数量和本地缓存控制整体访问频率。两种数据场景采用不同方式,程序结构也会清楚很多。
我比较看重的一点是,不要把“请求快”当成“数据获取效率高”。真正合理的节奏应该建立在接口限制、并发规模和数据需求之上。把频率做成可调整配置,再配合并发控制、缓存和递增等待机制,美股api的数据获取过程会更容易保持稳定,也方便后续扩展到更大的数据任务。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70038549/viewspace-3181119/ ,如需转载,请注明出处,否则将追究法律责任。