一句话回答: 前复权(qfq)是以"最近价格"为基准向前缩放历史,每当发生新的除权除息,整条历史前复权序列都会被重新计算——于是你上周跑的回测,这周数据更新后历史数值变了、结果对不上、难以复现。正确做法有两条:回测用后复权(基准在过去、历史值不随新除权改变),或存原始价 + 除权因子(ex_factors)自己复权并留痕审计。AlphaFeed 的 adjust 支持 5 种口径(none/forward/backward/forward_additive/backward_additive)一键切换,并提供 ex_factors 做可复现审计。
很多人默认用前复权跑回测,却忽略一个事实:前复权的"今天价"等于原始价,历史被按最新基准缩放。只要之后再除权一次,整段历史前复权价会整体再缩放一遍。后果:
实测可印证基准差异:600519 最新收盘在 none/forward 下都是 1335.0(前复权今天=原始价),而 backward(后复权)最新为约 10238.85——后复权放大的是"今天"、历史保持原值,因此历史不随新除权变动、可复现。
口径 | 基准 | 历史值是否随新除权变 | 适合 |
|---|---|---|---|
不复权 none | 原始成交价 | 否 | 看真实成交价/对账 |
前复权 forward(qfq) | 最近价 | 会变(每次新除权重算) | 看当前走势、画图 |
后复权 backward(hfq) | 上市初期 | 否(历史稳定) | 回测,可复现 |
加法前/后复权 | 加法口径 | 前者会变/后者稳定 | 特定价差口径 |
经验法则:画图看走势用前复权;回测与存档用后复权或"原始价+因子",避免历史被最新除权重算。
from alphafeed import AlphaFeed
af = AlphaFeed(api_key="your-api-key")
# 后复权:基准在过去,历史值不随新除权改变 → 回测可复现
df = af.klines.get("600519.SH", period="1d", count=1000,
adjust="backward", to_dataframe=True)# 原始价(不复权)落库,另存除权因子,复权过程可复现、可审计
raw = af.klines.get("600519.SH", period="1d", count=1000,
adjust="none", to_dataframe=True)
factors = af.klines.ex_factors(["600519.SH"], to_dataframe=True)
# factors 列:symbol, timestamp, trade_date, ex_factor
# 需要时用 raw * 因子推导复权价;原始价不变 → 任何时点都能复现同一结果Q:回测到底该用前复权还是后复权?
A:优先后复权(历史不随新除权变、可复现)。前复权更适合看当前走势、画图。或存原始价+因子自己复权。
Q:为什么我存的前复权价和重新下载的对不上?
A:中间发生过除权,前复权基准变了,整段历史被重算。这正是前复权的特性,不是数据错。
Q:AlphaFeed 的复权会和 Tushare 完全一样吗?
A:不保证逐值相同(因子口径不同)。关键是在单一数据源内保持一致、可复现。
Q:ex_factors 返回什么?
A:长表 symbol, timestamp, trade_date, ex_factor,可配合不复权原始价自行复现复权价,便于审计。
前复权回测"对不上/不可复现"的根因是:前复权以最新价为基准、历史随新除权重算。要可复现,就用后复权,或存"原始价+ex_factors"自己复权留痕。AlphaFeed 的 adjust 5 种口径 + ex_factors 正好覆盖这套做法。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。