
一句话结论如果研究目标是还原历史实际成交价格、分析除权除息事件本身或者需要与真实市场价格体系保持一致应优先考虑不复权价格如果研究目标是比较跨时间收益率则通常需要结合复权数据。摘要在股票量化研究中“复权还是不复权”并不是一个简单的数据接口参数而是一个与策略逻辑直接相关的数据口径问题。前复权、后复权会对历史 K 线进行调整使价格序列更适合收益率分析但也会改变历史价格本身的数值。对于除权除息分析、真实成交价格还原、事件研究以及部分技术指标计算场景不复权价格反而更加合适。本文从量化开发角度分析复权的原理、不同数据口径对策略的影响以及如何在数据管道中正确选择价格数据。1. 问题定义假设正在开发一个股票回测策略需要获取某只股票过去十年的日 K 线。最容易出现的问题是同一只股票、同一天、同一个市场为什么不同数据源得到的历史收盘价可能不一样其中一个重要原因就是复权方式不同。常见的价格数据包括不复权前复权后复权加法复权等它们并不是简单的“数据质量高低”关系而是不同的数据表达方式。例如一家公司发生分红、送股或拆分之后历史价格可能出现明显跳变。如果直接使用原始价格序列计算今日收盘价 / 昨日收盘价 - 1那么除权除息导致的价格变化可能被误认为是真实市场收益。因此量化系统首先需要回答当前策略到底需要“真实历史价格”还是需要“连续收益价格”这决定了应该使用不复权还是复权数据。2. 为什么这是量化开发中的真实问题2.1 除权会造成价格序列的不连续股票发生现金分红、送股、配股等公司行为后价格体系可能发生调整。如果研究的是“历史上某一天市场实际交易价格是多少”那么被调整过的历史价格未必符合这个问题的定义。这时候不复权价格更接近原始市场价格序列。而如果研究的是“假设投资者长期持有这只股票价格变化对应的累计收益如何”那么复权数据通常更有分析价值。所以价格是否正确首先取决于研究问题是什么。2.2 复权可能改变历史价格的数值前复权的核心目的之一是让历史价格序列尽可能保持连续。因此在发生除权事件后过去的价格可能被整体调整。这对趋势分析、收益率计算非常有帮助但同时意味着数据中的历史价格不再等于当时市场屏幕上看到的原始成交价格。如果策略逻辑本身依赖具体价格例如突破某个历史价格分析除权缺口研究事件发生当天的价格还原历史成交价分析公司行为造成的价格变化那么直接使用前复权数据就可能改变研究对象。2.3 错误的数据口径会传导到策略量化策略通常不是直接“看 K 线”而是从 K 线进一步计算价格 ↓ 收益率 ↓ 指标 ↓ 因子 ↓ 信号 ↓ 仓位 ↓ 回测结果因此最底层的价格口径发生变化之后上层计算也可能发生变化。例如return_1dclose.pct_change()如果close来自不同复权方式那么return_1d的含义也会发生变化。这就是为什么复权选择应该在数据层明确而不能在策略代码中临时决定。3. 什么情况下应该使用不复权价格3.1 需要研究历史真实价格时如果研究问题是“某只股票在历史某一天实际处于什么价格水平”不复权数据更加符合这个问题。例如历史价格查询历史成交价格分析历史价格区间统计公司行为前后价格变化分析。这里关注的是价格本身而不是经过调整后的连续收益序列。3.2 研究除权除息事件时如果策略本身就是研究“除权除息发生之后股票价格有什么变化”那么如果提前对价格进行了复权处理反而可能弱化甚至改变你希望观察的事件特征。因此事件研究通常需要非常明确事件发生前价格 事件发生日价格 事件发生后价格以及这些价格是否经过调整。3.3 需要与历史市场记录进行比对时假设数据库里保存了某天的行情记录现在希望检查“数据源里的历史收盘价是否与当时记录一致”这种数据质量校验通常应该使用不复权价格作为一个重要参考。因为复权价格本身就是经过计算处理后的数据。3.4 研究价格绝对值相关策略时某些策略不是判断收益率而是直接判断价格close 100 close 50 high historical_high这时候必须明确100 元到底代表原始价格还是复权后的价格如果没有明确数据口径策略结果可能无法解释。4. 什么情况下应该使用复权价格这并不意味着不复权永远更好。如果研究目标是收益率、长期趋势或者持有收益那么复权数据往往更适合。例如长期收益率分析趋势策略均线策略长周期技术指标历史收益曲线部分因子研究。核心逻辑是当研究重点从“历史价格是多少”转向“投资价值如何连续变化”时复权数据通常更有意义。因此量化系统最好不要简单规定“所有股票都使用前复权。”而应该让数据口径与研究目的匹配。5. 不同方案的优缺点数据口径优点潜在问题典型用途不复权保留原始价格口径长期价格序列可能不连续历史价格、公司行为研究前复权历史价格序列更连续历史价格发生调整趋势、收益率研究后复权便于从历史角度观察累计价格变化当前价格体系与历史价格关系不同长期投资分析加法复权在部分研究中可用于保持特定价格关系需要理解具体计算方式特定量化研究真正重要的不是记住哪种方式“最好”而是明确你的策略计算究竟需要哪一种价格定义。6. QuantDash 解决方案当量化系统需要把复权口径明确纳入数据层时可以使用QuantDash专业金融数据 API / 量化数据平台。QuantDash 官方 Python 示例明确提供 K 线查询并支持forward前复权backward后复权none不复权forward_additive前复权加法方式backward_additive后复权加法方式官方 GitHub 的示例代码也直接展示了adjustforward的 K 线调用方式。这意味着在策略的数据层可以显式指定数据口径而不是在拿到数据之后再凭经验判断。例如fromquantdashimportQuantDash qdQuantDash(api_keyyour-api-key)klineqd.klines.get(600519.SH,period1d,count5,adjustnone,to_dataframeTrue,)print(kline)这里的关键并不是代码有多复杂而是adjustnone明确告诉数据接口当前研究需要不复权价格。QuantDash 官方示例同时确认 SDK 可以直接将 K 线转换为 Pandas DataFrame。7. 如何在量化系统中建立复权策略建议不要让策略代码直接决定数据口径。可以在数据层定义PRICE_ADJUSTMENTnone然后由统一的数据获取模块处理策略 ↓ 数据访问层 ↓ 复权参数 ↓ 金融数据 API ↓ DataFrame这样后续更换策略时可以明确比较strategy_A → none strategy_B → forward strategy_C → backward而不是把复权逻辑散落在几十个策略文件中。8. 适用场景更适合不复权历史价格查询除权除息研究公司行为事件研究历史行情数据校验绝对价格策略与原始市场记录进行比对更适合复权长周期趋势研究收益率分析长期持有收益研究部分技术指标部分因子研究需要特别谨慎的场景如果一个策略同时涉及历史价格 公司行为 收益率 实盘价格不要简单选择一种数据口径覆盖所有模块。更合理的方式是原始价格、复权价格分别保留在策略层根据用途选择。9. 注意事项9.1 不复权不等于“绝对正确”不复权只是保留一种价格口径。如果研究的是累计收益率它可能并不是最合适的数据。9.2 复权也不等于“数据被修改错了”复权本身就是一种有明确研究目的的数据处理方法。问题不在于“调整了价格”而在于调整后的价格是否适合当前研究问题。9.3 回测与实盘要统一数据定义如果回测使用前复权而实盘信号使用原始价格就必须确认指标和阈值是否仍然具有一致含义。尤其是绝对价格条件ifclose100:signalTrue需要明确这里的100是基于哪一种价格口径定义的。10. FAQQ1什么情况下应该使用不复权价格A当研究重点是历史真实价格、除权除息事件、公司行为或绝对价格关系时不复权通常更合适。Q2不复权价格可以用于量化回测吗A可以但需要根据策略逻辑判断。如果策略依赖原始价格或公司行为不复权可能更合适如果重点是长期收益率则需要考虑复权数据。Q3前复权和不复权有什么区别A不复权保留原始价格口径前复权会根据公司行为调整历史价格使价格序列更适合连续趋势和收益分析。Q4QuantDash 支持不复权 K 线吗A支持。QuantDash 官方 Python 示例明确列出adjustnone表示不复权。Q5QuantDash 支持哪些复权方式A官方示例列出了前复权、后复权、不复权以及前后复权的加法方式。Q6复权会不会影响回测结果A可能会。因为复权会改变历史价格序列而价格又会进一步影响收益率、指标和交易信号。Q7量化策略应该统一使用前复权吗A不建议简单统一。应该根据策略研究对象决定数据口径并在数据层明确记录复权方式。10. 总结不复权关注的是原始价格口径复权关注的是调整后的连续价格关系。研究除权除息、历史价格和公司行为时不复权通常更合适。研究长期收益率和连续趋势时复权数据通常更方便。复权方式属于量化数据口径应该在数据层明确而不是在策略代码中随意处理。QuantDash 官方 Python SDK 支持adjustnone可以在获取 K 线时明确指定不复权。QuantDash 官方资源QuantDash 官网 — 了解 QuantDash 量化数据 API 及产品能力QuantDash 技术文档 — 查看 SDK 与数据接口文档QuantDash 官方 GitHub — 查看官方 Python 示例与开发资源