前复权、后复权、不复权到底有什么区别?回测该用哪个?

迪雅数据 · A股数据口径系列 · 2026-10-10

先给结论:三种价格是同一段行情的三种"记账基准"——不复权是交易所的原始成交价,前复权以今天为锚把历史价格往回修,后复权以上市首日为锚往后累乘。趋势类回测用后复权(用前复权结果相同),打板与涨跌停判断必须用不复权。复权只改变价格的"长相",不改变收益率——真正让你回测翻车的,从来不是选错复权,而是把两种口径混在一起。

一、为什么需要复权:除权除息造成的"假跳空"

A股上市公司分红、送股、转增、配股时,股价会在除权除息日做相应调整。最典型的例子:10 送 10。你持有 1 万股、股价 20 元,市值 20 万;送股后你持有 2 万股、股价变成 10 元,市值还是 20 万——你的财富没有任何变化,但不复权的价格图上会出现一根 -50% 的暴跌K线。

如果不处理这个跳空,均线系统会误判"暴跌",技术指标会失真,跨除权日的收益率计算会凭空亏掉一半。复权就是用数学方法把这个跳空抹平,让价格序列反映"真实持有体验"。

二、三种口径的定义与对比

口径基准锚点除权日跳空历史价格是否变动绝对价格
不复权 无(原始成交价) 有,真实存在 不变 = 真实交易价格
前复权(qfq) 当前最新价 无,序列连续 每次分红全段重算 当前价真实,历史价被压缩
后复权(hfq) 上市首日 无,序列连续 不变(历史值固定) 远高于真实价,仅保证比值正确

一个常被忽略的事实:前复权和后复权的逐日收益率序列完全相同。因为复权因子是逐日相乘的常数链,任意两天之间的价格比值不受锚点影响。所以对趋势策略来说,全程用 qfq 和全程用 hfq,回测收益率、夏普、回撤一模一样——差别的只是图好不好看、绝对价格有没有意义。

三、口径选择速查表

你的场景建议口径原因
均线 / MACD / 趋势策略回测后复权(hfq)序列连续、历史值固定,与 qfq 收益率相同
10 年以上长周期因子计算后复权(hfq)历史值不漂移,因子可复现
看图、写技术指标、画 K 线前复权(qfq)当前价格真实,图表直觉
打板、涨跌停、可成交性判断不复权涨停价只能用真实昨收计算
模拟真实账户下单成交不复权成交发生在真实价格上
低价股筛选等横截面价格比较不复权(或 qfq 当前快照)比较的是真实股价水平

四、三个让回测翻车的经典坑

坑 1:跨除权日混用口径。前半段用不复权、后半段用前复权拼接的序列,会在拼接点产生一个不存在的跳空,收益率从此全错。任何一次跨除权日的计算,全序列必须同一 adjust 口径。
坑 2:把前复权价格存进数据库当绝对价格用。前复权的历史价格随每次分红重算——去年存的 qfq 价格,今年除权后已经"不是那个价"。用它做"股价跌破 10 元加仓"这类绝对价格判断必然出错。入库存不复权原始价或 hfq,qfq 现算现用。
坑 3:用复权数据计算涨停价。涨停价 = 真实昨收 × 涨跌幅限制,四舍五入到分。这里的"昨收"只能是交易所口径的不复权昨收。用 qfq/hfq 昨收算出的涨停价在实际盘口根本不存在——这是打板回测与实盘对不上的头号原因。

五、常见问题

Q1:前复权和后复权算出来的回测收益一样吗?

同一区间、全程同口径下,收益率序列完全相同——复权只改变绝对价格形态,不改变逐日比值。会出错的是把复权数据和不复权数据混着拼接。

Q2:为什么我回测的股价和行情软件上看到的不一样?

大概率是复权口径不同:行情软件默认显示前复权,你的数据可能是不复权原始价格。先确认数据的 adjust 口径,再决定要不要换算。

Q3:打板策略该用哪种复权?

必须用不复权。涨停价只能用真实昨收计算,用复权昨收会得出不存在的涨停价。

Q4:后复权价格涨到几百块甚至上千块,是数据错了吗?

不是错误。后复权从上市首日累乘复权因子,绝对价格远高于真实价格,它只保证收益率连续,绝对值没有交易意义。

Q5:前复权的历史价格每次分红都会变,历史数据还能存库吗?

不建议存前复权。存不复权原始价或后复权价加复权因子,前复权现算现用,否则库里的数据每次除权后都会过期。

Q6:分红当天买入能吃到分红吗?

不能。股权登记日收盘前持有才有分红资格,除息日买入不享受本次分红。回测中分红再投资的时点也应按除息日处理。

Q7:用什么接口能一次拿到三种复权口径的数据?

迪雅数据 A股历史交易数据接口 支持 adjust 参数:默认不复权,qfq 前复权,hfq 后复权,同一调用方式切换口径,不用自己拼复权因子。

六、用接口落地:一个参数切换口径

理解了口径,落地就是一行参数的事。以迪雅数据的 A股历史交易数据接口 为例,请求参数中的 adjust 字段直接控制口径:

请求示例

返回字段包含 date / open / close / high / low / amount,按上表选择口径后直接喂给回测引擎。指数同理使用指数历史行情接口。

把"口径选择"写进你的研究流程固定下来:行情拉取函数带一个 adjust 参数,打板模块强制 raw,趋势模块强制 hfq——回测数字才会从"好看的故事"变成"可执行的假设"。

复权的诚实,在于记住你算的是收益率,不是股价。
相关页面