外观
复权对 ETF 轮动策略的影响分析
做过量化的朋友大概都有这样的经历:回测曲线漂亮得不像话,一上实盘却处处掉链子。很多时候问题不是出在策略逻辑上,而是出在价格数据本身——更具体地说,是复权方式选错了。
ETF 轮动策略尤其容易踩坑:ETF 会定期分红,高股息 ETF 甚至一年分红两到四次。如果复权方式处理不当,不仅动量因子会排错序,连持仓收益都会算错,实盘和回测会越跑越远。
本文将用最通俗的方式带你彻底理解复权,包括:
- 什么是复权价
- 前复权 / 后复权的计算方式
- 什么是等比复权,为什么必须要用等比复权
- 等比复权的计算公式
- 策略回测中复权的正确用法(动量 vs 持仓收益)
- 什么是动态复权
一、什么是复权价?
1.1 分红、送股会让股价"凭空下跌"
先看一个例子。假设你持有某 ETF,昨日收盘价 10.00 元,今天该 ETF 分红 0.50 元/份(现金),那么今天开盘前,该 ETF 的除息参考价会被交易所自动调整为:
除息参考价 = 10.00 - 0.50 = 9.50 元股价看起来"跌了"5%,但你的总资产并没有减少——因为 0.50 元现金已经打到账户里了。这种由分红、送股、配股等行为引起的价格跳空,叫做除权除息。
除权除息带来的问题是:价格的时间序列出现了一个不反映涨跌的跳空缺口。如果直接拿这样的原始价格做技术分析,均线、动量、突破信号全部会误判。
1.2 复权:把"不是真跌"的跳空抹平
复权(Adjustment)的目的,就是把除权除息造成的"假跌"抹平掉,使价格序列变得连续可比,真实反映投资者持有该资产的累计收益。
一句话概括:复权价 = 把分红、送股的影响折算回去之后的"可比价格"。
常见的复权方式有三大类:
| 类型 | 英文 | 基准 | 特点 |
|---|---|---|---|
| 不复权 | Raw / None | 原始价格 | 完全真实,但有跳空 |
| 前复权 | Backward Adjusted | 以"当前价"为锚 | 历史价格被向下调整 |
| 后复权 | Forward Adjusted | 以"历史起点"为锚 | 未来价格被向上累积 |
前复权:保持当前价格不变,将历史价格进行增减,从而使股价连续。 前复权用来看盘非常方便,能一眼看出股价的历史走势,叠加各种技术指标也比较顺畅,是各种行情软件默认的复权方式。 这种方法虽然很常见,但也有两个缺陷需要注意。
- 1.为了保证当前价格不变,每次股票除权除息,均需要重新调整历史价格,因此其历史价格是时变的。 这会导致在不同时点看到的历史前复权价可能出现差异。
- 2.对于有持续分红的公司来说,前复权价可能出现负值。
后复权:保证历史价格不变,在每次股票权益事件发生后,调整当前的股票价格。 后复权价格和真实股票价格可能差别较大,不适合用来看盘。 其优点在于,可以被看作投资者的长期财富增长曲线,反映投资者的真实收益率情况。
在量化投资研究中普遍采用后复权数据。
二、复权价是怎么算出来的?
2.1 前复权:把分红从前一日价格里"减掉"
普通前复权的思路非常朴素——把每次分红和送转的影响,反向叠加到除权前一日的价格上。
以一次简单的现金分红为例:
| 日期 | 事件 | 原始价 | 前复权价 |
|---|---|---|---|
| D-1 | 除权前一日 | 10.00 | 9.50(向下调整) |
| D | 除权当日派息 0.50 元 | 9.50 | 9.50(保持不变) |
| D+1 | — | 9.60 | 9.60(保持不变) |
核心公式:
前复权价 D-1 = 原始价 D-1 - 现金分红
= 10.00 - 0.50
= 9.50如果同时有送转股(例如 10 送 2,即送转比例 0.2)和配股,通用公式是:
前复权价_(D-1) = ( 原始价_(D-1) - 现金分红 + 配股价 × 配股比例 ) / ( 1 + 送转比例 + 配股比例 )注意:普通前复权是逐次加减处理的——先减去分红,再除以送转比例。
2.2 后复权:把分红"累加"到未来价格上
普通后复权的思路正好相反:保持历史价格不变,将每次分红和送转的影响"累加"到除权当日及之后的所有价格上。
| 日期 | 事件 | 原始价 | 后复权价 |
|---|---|---|---|
| D-1 | 除权前一日 | 10.00 | 10.00(保持不变) |
| D | 除权当日派息 0.50 元 | 9.50 | 10.00(向上还原) |
| D+1 | — | 9.60 | 10.11(按比例累加) |
用一句话总结:
前复权是"降低历史",后复权是"抬高未来",两者在"涨跌幅"上应该等价——但事实并非如此。
这就引出了下一节的核心问题:普通复权方式会导致涨幅失真。
三、普通复权的"致命缺陷":涨幅失真
3.1 为什么"简单加减"会出问题?
先看一个真实场景。某 ETF 连续多次高分红,按照普通前复权的算法逐次做减法,历史价格会不断被往下压。压到什么程度?极端情况下会被压到负数——这显然不符合任何真实市场的逻辑。
在迅投 QMT 社区的一个实测案例中,一只持续高分红的股票在普通前复权模式下,历史价格已经被推到了 负数。这意味着 K 线图上会画出不存在的负价,你写的基于绝对价格的策略条件全部报废。 (详见参考资料 迅投社区 - 聊聊除权发生日的持仓涨幅计算)
3.2 涨幅对比:普通前复权 vs 真实涨幅
更严重的问题是涨幅失真。我们来做一个简单推演。
假设某 ETF:
- 除权前一日原始收盘价 c0 = 10.00 元
- 除权当日派息 0.50 元,不送转
- 除权当日真实收盘价 c1 = 10.25 元
【真实持有人的涨幅】
作为持有人,你昨日持仓市值 10.00 元,今日现金分红 0.50 元 + 股票市值 10.25 元 = 10.75 元,真实涨幅:
真实涨幅 = ( 10.75 / 10.00 ) - 1 = 7.50%【普通前复权下的涨幅】
普通前复权把历史价从 10.00 减为 9.50,今日价不变仍为 10.25:
前复权涨幅 = ( 10.25 / 9.50 ) - 1 = 7.89%【普通后复权下的涨幅】
后复权把今日价从 10.25 抬高为 10.78(= 10.25 × 10.00 / 9.50),历史不变:
后复权涨幅 = ( 10.78 / 10.00 ) - 1 = 7.80%三者对不上!真实涨幅 7.50%、前复权 7.89%、后复权 7.80%,都有偏差。
原因:普通复权做的是加减法,但收益率的本质是比率。要注意,分红后拿到的是现金,这部分本身并不会自动产生额外收益;问题不在“分红现金继续增值”,而在于用加减法改了价格再去算比率,分子和分母的对应关系被扭曲了。分红越大、分红次数越多,这种扭曲在除权日附近越明显,偏差也越容易累积。
这就是普通复权会让涨幅失真的本质原因,也是动量、波动率、夏普等任何跟涨跌幅相关的因子都会被污染的根源。
四、等比复权:为比率计算而生
4.1 核心思路
既然加减法出错,那就改用乘除法——每次除权都按"涨幅比例"作为调整系数,然后把历史价格乘以这个系数,而不是减去一个绝对金额。这就是等比复权(Proportional Adjustment)。
对前面那个例子:
除权当日的实际涨幅是 7.50%(把分红和现价一起算进去),所以复权调整系数就是:
factor = ( 除权日现价 ) / ( 除权前一日原始价 × ( 1 + 真实涨幅 ) )换个更直观的写法——等比前复权的"单次复权因子":
factor = (c1) / (c0 + 分红 - 配股价 × 配股比例) × (1 + 送转比例 + 配股比例)这里的 c0 是除权前一日的原始价,c1 是除权当日的原始价。计算出来的 factor 就是一个等比例系数。
然后:
等比前复权价(所有历史日) = 原始价(该日) × factor如果历史上有多次分红除权,就把每次的 factor 连乘起来,再和原始价相乘。
4.2 验证:等比复权的涨幅是对的
继续用上面的例子验证。等比前复权下:
等比前复权 c0 = 10.00 × (10.25 / 10.75) ≈ 9.535
等比前复权 c1 = 10.25(当日价保持不变)
等比前复权涨幅 = ( 10.25 / 9.535 ) - 1 = 7.50%✅ 正好等于真实持仓涨幅 7.50%。
这就是**等比前复权之所以被称为"正确复权"**的原因——无论是否跨越除权日,涨幅计算永远是准确的。
4.3 等比复权处理分红,为什么是合理的?
很多朋友第一次看到等比复权,会担心一个问题:
分红明明是现金流,为什么可以用一个价格比例系数去处理?这会不会"把分红算丢了"?
这个担心非常好。判断是否合理,关键看两条:
- 资产守恒:分红前后,总资产是否连续;
- 收益一致:复权后算出来的涨幅,是否等于真实持有人的账户涨幅。
对仅有现金分红(不送转、不配股)的场景,可以直接推导:
设:
P_{t-1}:分红前一日原始收盘价D_t:每份现金分红P_t:分红当日原始收盘价
真实持有人的单日收益率应为:
r_t = (P_t + D_t) / P_{t-1} - 1等比复权定义一个当日调整因子 k_t,使得:
P_t / (P_{t-1} × k_t) - 1 = r_t把 r_t 代入可得:
k_t = P_t / (P_t + D_t)于是分红前一日的等比复权价就是:
P'_{t-1} = P_{t-1} × k_t = P_{t-1} × P_t / (P_t + D_t)再算复权口径涨幅:
P_t / P'_{t-1} - 1
= (P_t + D_t) / P_{t-1} - 1
= r_t✅ 完全等于真实收益率。
这说明:等比复权并不是把分红忽略掉,而是把“价格收益 + 现金分红收益”合并成同一口径的收益率序列。因此它在做动量、波动率、夏普、回归斜率这类"只关心收益率"的计算时是合理且严谨的。
通俗地说,等比复权就像把分红在当日按该基金价格立刻再投入。
但请注意:合理不等于万能。等比复权是把分红"折叠"进价格序列,适合因子和信号计算;如果要做账户净值、可用现金、再投资模拟,必须使用"真实价格 + 动态复权"。
4.4 等比复权的两大优点
| 优点 | 具体说明 |
|---|---|
| 不会出现负价格 | 因为每次只是乘一个正系数(通常略小于 1),无论多少次分红都不会把价格压到负数 |
| 涨幅始终真实 | 每次除权位置的价格变化都与真实持仓涨幅一致,跨除权日的收益率不失真 |
五、策略回测中复权的正确用法
讲完了原理,终于来到最关键的一步:在 ETF 轮动策略中,到底应该怎么使用复权?
答案是分场景使用不同的价格。
5.1 动量因子计算:必须使用等比复权价
所有与价格涨跌幅相关的量化因子,都必须使用等比复权价计算,否则会被分红事件严重干扰。典型的受影响因子包括:
- 简单动量:
(P_今 - P_N天前) / P_N天前 - 斜率动量:对数价格做线性回归
- 加权斜率动量:带权重的线性回归
- RSRS 动量:基于最高价/最低价的相对强弱
- 波动率:收益率序列的标准差
- 夏普比率、Calmar 比率:所有基于收益率的评价指标
为什么必须是等比复权? 以斜率动量为例:
python
# 伪代码:斜率动量计算
y = np.log(close_prices) # 对数价格
slope, _ = np.polyfit(x, y, 1)这里的对数价格 log(P) 对应的斜率,物理含义就是每日对数收益率。如果 close_prices 是不复权价或普通复权价,除权日的价格跳空会让 log(P_t) - log(P_{t-1}) 直接出现一个巨大的负脉冲,线性回归结果完全失真。
只有使用等比复权价,对数价格序列才是连续、光滑的,动量排名才有意义。
一句话规则:
🔴 凡是用价格算"涨跌幅"或"因子分数"的地方,必须用等比复权价(推荐等比前复权或等比后复权)。
5.2 持仓收益计算:用真实价 + 动态复权
这里有一个非常容易被忽略的点:动量因子用等比复权价算排名没问题,但计算策略净值时,不能直接用等比复权价算收益。
为什么? 因为你的资金账户真实持有的是份额,成交价是真实的市场价,分红到账的是真实的现金。如果在净值模拟时用"等比复权价"直接算涨幅:
- 分红到账的现金没有被独立跟踪,而是被隐含在了复权价里;
- 买卖成交价如果用复权价,则与实盘无法对应(实盘撮合的是真实价);
- 持仓期间跨越除权日时,份额变化(送股/拆股)未被真实反映。
正确的做法是模拟实盘账户的运作方式——这就是所谓的动态复权。
六、什么是动态复权?
6.1 动态复权的定义
动态复权(Dynamic Adjustment)不是一种"新的价格",而是一种账户级的模拟记账方式:
当持仓的标的发生分红、送股、拆股、合并、配股等事件时,回测系统按照真实市场规则,同步调整账户中的持股数量和现金余额,使得账户状态与"真的有个账户在持仓"完全一致。
引用 joinquant(聚宽)官方文档对"拆分合并与分红"的处理方式(JoinQuant 文档):
| 市场事件 | 动态复权账户处理方式 |
|---|---|
| 现金分红 | 按持股数量 × 每股分红金额,现金余额增加 |
| 送股 / 转增 | 按送转比例,持股数量增加 |
| 拆股(splitRatio > 1) | 持股数量按拆股比例增加,持股单价下降 |
| 合并(splitRatio < 1) | 持股数量按合并比例减少,持股单价上升 |
| 配股 | 扣除现金,增加持股数量(若策略中参与配股) |
6.2 动态复权下,策略净值如何计算?
以一次分红为例,直观演示:
【初始状态】
- 持仓:某 ETF 10000 份
- 现金:0
- 当日收盘价:10.00 元
- 账户总市值:10000 × 10.00 = 100,000 元
【次日除息:每份派息 0.50 元】
动态复权处理:
- 持股数量不变:10000 份
- 现金增加:10000 × 0.50 = 5,000 元
- 除息参考价:9.50 元
账户总市值:10000 × 9.50 + 5,000 = 100,000 元(不变,合理!)
【除息日实际收盘价 9.60 元】
账户总市值:10000 × 9.60 + 5,000 = 101,000 元
当日涨幅 = ( 101,000 / 100,000 ) - 1 = 1.00%
用等比前复权价验证一下:
等比前复权_D-1 = 10.00 × (9.60 / (9.60 + 0.50)) = 10.00 × 9.60 / 10.10 ≈ 9.505
当日涨幅 = (9.60 / 9.505) - 1 ≈ 1.00% ✅ 吻合两种算法得到的涨幅完全一致。但动态复权的优势在于:
- 现金分红可以在账户中实际流转,下一次调仓时可以用于重新买入其他标的;
- 送股/拆股后的持股数量变化也是真实记录的,不会隐藏在"复权系数"里;
- 实盘迁移时,策略逻辑一一对应真实账户操作,不会出现回测用一套、实盘用另一套的问题。
6.3 单次动态复权的数学表达
在一些量化平台(如迅投 QMT)中,动态复权也被称为单次动态前复权,它的核心思想是:只在持仓跨越当次除权日时,对"前一日收盘价"进行一次复权,用于计算当日的真实涨幅。
单次复权因子 = (除权日原始价 + 分红) / (1 + 送转比例) / 除权前一日原始价
复权前收价 = 除权前一日原始价 × 单次复权因子
当日涨幅 = 今日原始价 / 复权前收价 - 1这里"前复权"这个词指的是"把前一日收盘价调整到除权后的口径",而不是修改所有历史数据。这才是实盘中计算"当日持仓涨幅"的正确方式。
七、三种价格在 ETF 轮动策略中的正确分工
把前面所有内容总结如下:
在 ETF 轮动策略中,三类操作应使用不同的价格口径:
动量因子计算 / 排名打分:使用等比复权价(等比前复权或等比后复权),保证跨除权日的涨跌幅不失真。
调仓下单 / 成交价模拟:使用真实原始价(不复权价),保证成交价与实盘对应。
持仓期间收益与净值计算:使用动态复权(账户级处理),分红入账、送股增持、拆股合并自动处理。
次方量化平台的处理方式
在 次方量化 的回测与实盘系统中:
- 动量因子(简单动量、斜率动量、加权斜率动量、RSRS 动量)统一使用等比后复权进行计算,保证跨除权日的动量排名稳定可信;
- 持仓净值使用动态复权方式模拟真实账户,分红按真实金额进入现金账户,送股按真实比例增加持股数量;
- 回测结果与实盘轨迹高度一致,避免"回测漂亮、实盘掉链子"的典型问题。
八、总结
复权问题看似只是"价格处理"这样一个技术细节,但它直接决定了 ETF 轮动策略的回测真实性与实盘可迁移性。
| 核心结论 | 关键要点 |
|---|---|
| 复权的目的 | 消除分红、送股等事件造成的"假跳空",保证价格可比 |
| 普通复权的缺陷 | 加减法导致涨跌幅失真,高分红标的下会累积出负价格 |
| 等比复权的优势 | 按比例累乘,涨跌幅与真实持仓收益完全一致 |
| 动态复权的本质 | 不是"一种价格",而是账户级的记账方式,真实还原分红/送股流程 |
| 动量因子 | 必须使用等比复权价计算 |
| 持仓收益 | 必须使用原始价 + 动态复权模拟真实账户 |
一句话总结:
等比复权用来"打分",真实价加动态复权用来"结账"。 两者各司其职,才能让 ETF 轮动策略的回测曲线真正反映你未来能拿到的收益。