一句话回答: 前复权价不是"固定值"——每次分红送股后,历史前复权价都会整体缩放一次,直接把复权价存进数据库迟早和线上对不上。正确做法是用 AlphaFeed 存原始价(不复权)+ 除权因子(ex_factors),需要时再本地复现复权价。这样数据可审计、可复现,且和 SDK 的 adjust="forward" 结果逐行完全一致(误差 0)。
很多人把 adjust="forward"(前复权)的收盘价直接落库,几个月后发现:同一天、同一只票,历史前复权价变了。这不是 bug——前复权的定义就是"以最新价为基准向前缩放",每发生一次分红送股(除权),基准就变一次,整条历史序列会被重新缩放。
from alphafeed import AlphaFeed
import pandas as pd
af = AlphaFeed() # 读取 ALPHAFEED_API_KEY
symbol = "600519.SH"
raw = af.klines.get(symbol, period="1d", count=400, adjust="none",
to_dataframe=True).sort_values("trade_date").reset_index(drop=True)
ef = af.klines.ex_factors([symbol], to_dataframe=True).sort_values("trade_date")
print(ef[["trade_date", "ex_factor"]].tail(3).to_string(index=False))ex_factors 返回每个除权日的一条记录,字段见下表。ex_factor 是该次除权事件的调整比率(>1 表示当日发生了分红/送股导致的向下跳空)。
字段 | 含义 | 示例 |
|---|---|---|
| 标的代码 |
|
| 除权日毫秒时间戳 |
|
| 除权日(YYYY-MM-DD) |
|
| 该次除权的调整比率(每次事件一条) |
|
AlphaFeed 前复权的口径是:某交易日 t 的前复权价 = 该日原始价 ÷(所有除权日晚于 t 的 ex_factor 连乘积)。最新一段(在最后一次除权之后)除数为 1,即前复权价 = 原始价。
raw["td"] = pd.to_datetime(raw["trade_date"])
ex = ef.assign(td=pd.to_datetime(ef["trade_date"]))[["td", "ex_factor"]]
def forward_divisor(t):
later = ex.loc[ex["td"] > t, "ex_factor"] # 晚于当日的所有除权事件
return later.prod() if len(later) else 1.0
raw["divisor"] = raw["td"].apply(forward_divisor)
raw["qfq_close"] = raw["close"] / raw["divisor"]fwd = af.klines.get(symbol, period="1d", count=400, adjust="forward",
to_dataframe=True).sort_values("trade_date").reset_index(drop=True)
diff = (fwd["close"] - raw["qfq_close"]).abs()
print("最大绝对误差:", round(diff.max(), 6)) # -> 0.0
print("最大相对误差(%):", round((diff / fwd["close"]).max() * 100, 6)) # -> 0.0实测(茅台 600519.SH,400 个交易日):最大绝对误差 = 0.0,逐行完全一致。说明"原始价 + 因子"能无损复现 SDK 的前复权序列。
只落 原始 OHLC + 每次除权的因子 两张表,复权价永远现算:
表 | 列 | 说明 |
|---|---|---|
| symbol, trade_date, open, high, low, close, volume, amount | 原始价,写入后永不修改 |
| symbol, trade_date, ex_factor | 除权事件表,只在除权日 新增一行 |
增量更新时:K 线只追加新交易日;ex_factors 只在有新除权时追加。历史行永不被覆盖,天然可审计、可复现。
backward)反过来:以最早价为基准,历史价不变、最新价被放大,适合长周期收益复现;前复权适合看当前价位。可用同一套因子换基准点复现。amount,美股/港股 K 线 amount=0(用 volume 替代),与本文复权逻辑无关,但落库时要注意。Q:为什么我半年前存的前复权价现在对不上了?
A:因为期间发生了分红送股,前复权基准变了,历史序列被整体缩放。存原始价 + 因子就不会有这个问题。
Q:ex_factor 是累计的还是单次的?
A:是单次除权事件的比率。复现某日复权价要把该日之后的所有 ex_factor 连乘作为除数。
Q:需要付费吗?
A:klines.get/ex_factors 属基础能力,注册即有免费额度;大规模全市场批量与更高频调用见 Starter 及以上,详见定价页。
复权价是"派生量",会随除权漂移;原始价和除权因子才是"不变量"。用 AlphaFeed 存原始价 + ex_factors、需要时本地复现,既省带宽又能做到 误差 0、可审计、可复现——这才是能长期维护的复权数据方案。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。