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

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

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

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

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

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

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

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

python 复制代码
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,遍历即可:

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

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

python 复制代码
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 步:调并发与分批参数

python 复制代码
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 返回 DataFrame True 便于分析

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

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

python 复制代码
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)}")

关键坑与注意事项

  • 别用裸 for 循环取几百只 :串行慢且更易触发限频,能用 batch 就用 batch。
  • 并发不是越高越好 :max_workers 过大反而撞限频(429),从 8 起步按网络调。
  • 全市场分块 :几千只一次性 batch 内存与单请求都过重,按 200~500 分块并落盘更稳。
  • 批量里个别标的可能缺失:停牌/新股/退市可能返回空或缺键,遍历时判空跳过。
  • SDK 已内置重试:偶发 429/5xx 会自动退避重试,业务层不必自己写重试循环(详见限频/容错一文)。
  • 计时结果因网络而异:本文示例的提速倍数取决于标的数与网络,标的越多优势越大。

常见问题(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},内置并发与分批让它比朴素循环快数倍,再配合标的池分块,就能稳、快地完成从几只到全市场的取数。

参考

相关推荐
乌暮35 分钟前
综合案例:宠物电商系统
java·开发语言·spring·mvc·restful·1024程序员节
大文说跨境36 分钟前
亚马逊多店铺的图片素材怎么批量去重:EXIF 与哈希的处理流程
开发语言·php
上海运维Q先生1 小时前
PHP8.3.36升级修复手册----CVE-2026-109618 CVE-2026-109619
运维·php
2401_885885042 小时前
芬兰语音通知接口怎样对接?语音提醒接入流程
android·前端·python·php·语音识别
大风起兮云飞扬丶2 小时前
Java——枚举
java·开发语言
小灰灰搞电子2 小时前
Rust+Slint 实现高级动态消息提示框源码分享
开发语言·rust
Dev _2 小时前
Python解释器安装在系统级目录导致命令行用户‌没有权限‌向该目录写入文件
开发语言·python
qq_406981033 小时前
大白话rust系列08 当变量遮蔽遇上引用,探究变量遮蔽的本质
开发语言·后端·rust
喵了几个咪3 小时前
GoWind ShortPlay 拆解:不用模型的推荐闭环——埋点回流、三路召回与已看去重
开发语言·后端·微服务·golang·gowind
谙弆悕博士3 小时前
用 C 写了个 Windows 聊天室,踩了几个多线程和控制台的坑
c语言·开发语言·c++·windows·网络编程·聊天室