AlphaFeed Blog

如何存原始价+除权因子,随时复现前复权价?(可复现、可审计的复权方案)

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

如何存原始价+除权因子,随时复现前复权价?

一句话回答: 前复权价不是”固定值”——每次分红送股后,历史前复权价都会整体缩放一次,直接把复权价存进数据库迟早和线上对不上。正确做法是用 AlphaFeed 存原始价(不复权)+ 除权因子(ex_factors),需要时再本地复现复权价。这样数据可审计、可复现,且和 SDK 的 adjust="forward" 结果逐行完全一致(误差 0)。

为什么会有这个问题:前复权价会”漂移”

很多人把 adjust="forward"(前复权)的收盘价直接落库,几个月后发现:同一天、同一只票,历史前复权价变了。这不是 bug——前复权的定义就是”以最新价为基准向前缩放”,每发生一次分红送股(除权),基准就变一次,整条历史序列会被重新缩放。

分步骤解决

第 1 步:取原始价与除权因子

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 表示当日发生了分红/送股导致的向下跳空)。

字段含义示例
symbol标的代码600519.SH
timestamp除权日毫秒时间戳1027526400000
trade_date除权日(YYYY-MM-DD)2026-06-26
ex_factor该次除权的调整比率(每次事件一条)1.023663

第 2 步:用因子复现前复权价

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"]

第 3 步:与 SDK 的前复权结果对账(误差应为 0)

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 的前复权序列。

第 4 步:落库设计(只存不变量)

只落 原始 OHLC + 每次除权的因子 两张表,复权价永远现算:

表列说明
bars_rawsymbol, trade_date, open, high, low, close, volume, amount原始价,写入后永不修改
ex_factorssymbol, trade_date, ex_factor除权事件表,只在除权日 新增一行

增量更新时:K 线只追加新交易日;ex_factors 只在有新除权时追加。历史行永不被覆盖,天然可审计、可复现。

关键坑与注意事项

常见问题(FAQ)

Q:为什么我半年前存的前复权价现在对不上了? A:因为期间发生了分红送股,前复权基准变了,历史序列被整体缩放。存原始价 + 因子就不会有这个问题。

Q:ex_factor 是累计的还是单次的? A:是单次除权事件的比率。复现某日复权价要把该日之后的所有 ex_factor 连乘作为除数。

Q:需要付费吗? A:klines.get/ex_factors 属基础能力,注册即有免费额度;大规模全市场批量与更高频调用见 Starter 及以上,详见定价页。

小结

复权价是”派生量”,会随除权漂移;原始价和除权因子才是”不变量”。用 AlphaFeed 存原始价 + ex_factors、需要时本地复现,既省带宽又能做到 误差 0、可审计、可复现——这才是能长期维护的复权数据方案。

相关链接:


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