如何用 Python 把 K 线重采样成任意周期?(3日线/2小时线的正确 OHLCV 聚合)
如何用 Python 把 K 线重采样成任意周期?
一句话回答: AlphaFeed 原生支持 1m/5m/15m/30m/60m/1d/1w/1M;要非标准周期(如 3 日线、2 小时线、半年线)就用 pandas resample 自己合成——关键是 OHLCV 必须按正确规则聚合:开盘=首值、最高=区间最大、最低=区间最小、收盘=末值、成交量/额=求和。用错聚合(比如对开盘价取均值)会得到错误的 K 线。
为什么会有这个问题 / 传统做法的痛点
原生周期够用大多数场景,但有时需要自定义周期(3 日波段、2 小时级别)。直接对所有列取 mean() 是最常见的错误——价格要分别取首/高/低/末,成交量要求和。另外还要注意用前复权价、以正确的时间索引对齐、以及最后一根「未完成周期」的处理。
分步骤解决(每步配可运行代码)
第 1 步:取原始 K 线并设时间索引
from alphafeed import AlphaFeed
import pandas as pd
af = AlphaFeed() # 读取 ALPHAFEED_API_KEY
df = af.klines.get("600519.SH", period="1d", count=250,
adjust="forward", to_dataframe=True)
df = df.sort_values("trade_date").reset_index(drop=True)
df["dt"] = pd.to_datetime(df["trade_date"])
k = df.set_index("dt")
第 2 步:定义正确的 OHLCV 聚合规则
AGG = {
"open": "first", # 开盘=区间第一根的开
"high": "max", # 最高=区间内最高
"low": "min", # 最低=区间内最低
"close": "last", # 收盘=区间最后一根的收
"volume": "sum", # 成交量=求和
"amount": "sum", # 成交额=求和
}
| 字段 | 聚合方式 | 为什么 |
|---|---|---|
| open | first | 周期首根的开盘 |
| high | max | 周期内最高 |
| low | min | 周期内最低 |
| close | last | 周期末根的收盘 |
| volume/amount | sum | 累加 |
第 3 步:重采样成任意周期
# 3 日线(按自然日 3D;要按交易日请见下方注意事项)
k3d = k.resample("3D").agg(AGG).dropna(subset=["open"])
# 周线(周五收盘对齐)、半月、月线等
kw = k.resample("W-FRI").agg(AGG).dropna(subset=["open"])
km = k.resample("ME").agg(AGG).dropna(subset=["open"])
print(k3d.tail(3)[["open", "high", "low", "close", "volume"]].to_string())
分钟线同理(先取分钟原始数据):
m = af.klines.get("600519.SH", period="5m", count=240, to_dataframe=True)
m = m.sort_values("trade_date")
m["dt"] = pd.to_datetime(m["trade_time"])
k30 = m.set_index("dt").resample("30min").agg(AGG).dropna(subset=["open"]) # 5m→30m
第 4 步:校验聚合正确性
# 抽查:某个 3 日窗口的 high 应等于其内部各日 high 的最大
chk = k.resample("3D").agg(AGG).dropna(subset=["open"]).iloc[-1]
raw_last3 = k.loc[k.index >= k.index[-3]]
assert abs(chk["high"] - raw_last3["high"].max()) < 1e-6
assert abs(chk["volume"] - raw_last3["volume"].sum()) < 1e-6
print("聚合校验通过:high=max、volume=sum")
关键坑与注意事项
- 别对价格取均值:开/高/低/收必须分别 first/max/min/last,
mean()会得到错误 K 线。 - 用前复权价:跨除权日重采样要用
adjust="forward",否则合成 K 线失真。 - 自然日 vs 交易日:
resample("3D")按自然日分箱,含周末空箱(已dropna);若要严格「每 3 个交易日」一根,应按行号分组(groupby(np.arange(len(k))//3))而非时间 resample。 - 周线对齐:A 股周线惯例以周五收盘对齐,用
W-FRI;用W默认周日对齐会不符习惯。 - 最后一根未完成:当前周期未走完时,最后一根是「进行中」的不完整 K,回测时按需剔除。
- 分钟线跨日:分钟重采样跨交易日/午休会产生空箱,
dropna掉或按交易时段分组处理。
常见问题(FAQ)
Q:为什么不直接用 resample 的 mean? A:K 线不是均值。开盘要取区间第一笔、收盘取最后一笔、最高/最低取极值、量额求和——各列聚合方式不同,统一 mean 是错的。
Q:想要「每 3 个交易日」而不是「每 3 个自然日」怎么办?
A:用行号分组:k.groupby(np.arange(len(k)) // 3).agg(AGG),这样严格每 3 根交易日合成一根,不受周末影响。
Q:周线为什么用 W-FRI?
A:A 股一周最后一个交易日通常是周五,用 W-FRI 让周线以周五收盘对齐,符合行情软件习惯。
Q:需要付费吗? A:取原始 K 线有免费额度;重采样是本地 pandas 操作、不涉及付费。批量/全市场取数需 Starter 及以上。详见定价页。
小结
非标准周期用 pandas resample + 正确的 OHLCV 聚合规则(first/max/min/last/sum)即可合成,别用 mean。记住用前复权价、分清自然日与交易日(严格 N 交易日用行号分组)、周线用 W-FRI、剔除未完成的最后一根。用 AlphaFeed 取原始 K 线,几行就能得到任意周期的正确 K 线。
相关链接:
- AlphaFeed 官网:https://alphafeed.org/
- Python SDK 快速开始:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
免责声明:本文仅为技术与数据接口使用示例,代码与逻辑仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。