AlphaFeed Blog

批量取数比循环单取快多少?用 AlphaFeed klines.batch 给多股票取数提速

工程化 · 代码验证于 2026-09-22

批量取数比循环单取快多少?用 AlphaFeed klines.batch 给多股票取数提速

一句话回答: 给几十上百只股票取 K 线,用 for 循环一只只调接口不仅慢,还容易触发限频。AlphaFeed 的 klines.batch(codes, ...) 一次就能批量取回(内置并发与自动分批),实测比朴素循环快数倍,返回 dict{symbol: DataFrame} 直接可用——这是多标的取数的正确姿势。

为什么会有这个问题 / 传统做法的痛点

新手取多只股票的写法通常是:

data = {}
for code in codes:
    data[code] = af.klines.get(code, period="1d", count=250)   # 串行、慢、易限频

标的一多,串行请求的网络往返(RTT)线性累加,几百只要等很久;而且高频串行请求更容易撞上接口限频(429)。正确做法是把「批量」交给 SDK:一次请求/内部并发取回所有标的。

分步骤解决(每步配可运行代码)

第 1 步:用 klines.batch 一次取回多只

from alphafeed import AlphaFeed

af = AlphaFeed()  # 读取 ALPHAFEED_API_KEY

codes = ["600519.SH", "000001.SZ", "601318.SH", "000858.SZ", "300750.SZ"]
data = af.klines.batch(codes, period="1d", count=250,
                       adjust="forward", to_dataframe=True)

print(type(data), list(data.keys()))      # dict{symbol: DataFrame}
print(data["600519.SH"].tail(2)[["trade_date", "close"]].to_string(index=False))

batch 返回一个字典,键是标准代码,值是该股的 DataFrame,遍历即可:

for sym, kdf in data.items():
    ret = kdf["close"].iloc[-1] / kdf["close"].iloc[0] - 1
    print(f"{sym}: 区间收益 {ret:+.2%}")

第 2 步:计时对比——循环 vs 批量

import time

def timed(fn):
    t0 = time.perf_counter(); out = fn(); return out, time.perf_counter() - t0

# 朴素循环
_, t_loop = timed(lambda: {c: af.klines.get(c, period="1d", count=250,
                                            adjust="forward", to_dataframe=True)
                           for c in codes})
# 批量
_, t_batch = timed(lambda: af.klines.batch(codes, period="1d", count=250,
                                           adjust="forward", to_dataframe=True))

print(f"循环 {t_loop:.2f}s  |  批量 {t_batch:.2f}s  |  提速 {t_loop / t_batch:.1f}x")

标的越多、网络 RTT 越高,批量相对循环的优势越明显;batch 内部并发把串行等待压平。

第 3 步:调并发与分批参数

data = af.klines.batch(codes, period="1d", count=250, adjust="forward",
                       to_dataframe=True, batch_size=50, max_workers=8)
参数含义建议
batch_size每批标的数量默认即可;过大单请求更重
max_workers并发线程数8~16 视网络而定,过高易撞限频
adjust复权方式算收益/指标用 forward
to_dataframe返回 DataFrameTrue 便于分析

第 4 步:全市场取数的正确姿势

要对全 A 取数,先用标的池拿代码,再分批 batch,避免一次性拉爆:

q = af.quotes.get(universes="CN_Stock", to_dataframe=True)
codes = q["symbol"].tolist()

all_data = {}
CHUNK = 200
for i in range(0, len(codes), CHUNK):
    part = af.klines.batch(codes[i:i + CHUNK], period="1d", count=60,
                           adjust="forward", to_dataframe=True)
    all_data.update(part)
    print(f"已取 {len(all_data)}/{len(codes)}")

关键坑与注意事项

常见问题(FAQ)

Q:batch 返回的顺序和我传入的一致吗? A:返回是 dict{symbol: DataFrame},按 symbol 键访问最稳;需要顺序就按传入 codes 遍历取值。

Q:batch 能跨市场混着取吗(A 股 + 港股 + 美股)? A:可以,传入的 codes 里混合 .SH/.SZ/.HK/.US 均可,按标准代码取回。

Q:某只票取失败会影响整批吗? A:不会整批失败;缺失的标的不会出现在结果字典里或返回空,遍历时判空即可。

Q:需要付费吗? A:小批量有免费额度;全市场标的池(universes)与大规模批量取数需 Starter 及以上。详见定价页。

小结

多标的取数的性能关键,是把「批量与并发」交给 SDK 而不是自己写串行循环。用 AlphaFeed 的 klines.batch 一次取回 dict{symbol: DataFrame},内置并发与分批让它比朴素循环快数倍,再配合标的池分块,就能稳、快地完成从几只到全市场的取数。

相关链接:


免责声明:本文仅为技术与数据接口使用示例,代码与逻辑仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。