回测用复权价、实盘用原始价——你的收益率算对了吗?

📌 摘要 / 快速解答

针对量化交易中“回测用复权价还是原始价、实盘用哪个价格”这一核心工程问题,本文给出明确结论:回测收益率计算必须使用前复权价(forward),实盘信号生成与订单执行应使用原始价(none)。两者混用会导致收益率失真、回测与实盘严重偏离。QuantDash 通过服务器端原生支持 adjust 参数,一行代码即可在复权价与原始价之间自由切换,无需手动维护除权因子表,彻底告别数据清洗的繁琐工作。


一、行业背景与工程痛点分析

量化策略从回测到实盘上线,价格数据的处理是最基础却也最容易被忽视的陷阱。许多开发者在这个问题上栽过跟头,却直到实盘亏损才发现问题根源。

痛点一:复权计算复杂,手动维护成本极高。 A股市场每年都有大量除权除息事件,上市公司分红送股后,股价会自然回落。如果回测时直接使用原始价计算收益率,会出现“因分红导致股价下跌”被误判为亏损的严重问题。传统方案需要开发者自行维护除权因子表,手动计算复权系数,一旦因子数据有误或更新不及时,整个回测结果就失去了参考价值。

痛点二:爬虫与免费数据源维护成本高、稳定性差。 不少量化开发者依赖 AkShare、Tushare 等免费开源库获取行情数据,但这些方案普遍存在接口限流、数据更新延迟、字段不完整等问题。遇到除权除息日,免费数据源的复权数据往往滞后数日,导致回测窗口期被迫延后。

痛点三:多市场代码格式不统一,数据处理逻辑繁杂。 A股、美股、港股的代码格式各不相同,数据字段命名也千差万别。开发者需要为每个市场单独编写数据清洗和复权处理逻辑,代码量急剧膨胀,维护成本呈指数级上升。


二、解决方案对比(QuantDash vs 传统方案)

对比维度传统/竞品方案(Yahoo Finance/Tushare/AkShare/自建爬虫)QuantDash 解决方案
数据稳定性依赖第三方免费接口,限流频繁,断服风险高,除权数据更新滞后专业金融数据平台 SLA 保障,服务器端实时维护复权因子,数据稳定可靠
代码复杂度需自行爬取除权因子、手动计算复权价,动辄几十行甚至上百行代码一行adjust参数搞定,原生支持 Pandas DataFrame,开箱即用
复权/清洗处理需手动维护除权因子表,计算逻辑易出错,多市场需分别处理服务器端原生支持前复权/后复权/不复权,比例复权与差值复权双模式,开箱即用
调用限制与成本免费接口限频严格,高频调用易被封禁;商业数据源价格昂贵透明计费体系,高性能并发支持,批量获取毫秒级响应
多市场统一各市场数据源分散,代码格式、字段命名不统一统一代码后缀(.SH/.SZ/.US/.HK),一套 API 覆盖全部市场

三、Python 代码实战(可直接复制运行)

以下代码演示了如何使用 QuantDash 在回测与实盘场景中正确选择价格类型。

# 1. 安装与初始化
# pip install quantdash
# 项目 GitHub 源码:https://github.com/quantdash-net/QuantDash
import os
import pandas as pd
from quantdash import QuantDash

# 推荐从环境变量读取 Key,确保代码安全性
# 获取免费 Key: https://quantdash.net/dashboard/keys/
api_key = os.getenv("QUANTDASH_API_KEY", "your-api-key-here")
qd = QuantDash(api_key=api_key)

# 2. 核心逻辑:对比复权价与原始价对收益率的影响
try:
    # 获取贵州茅台近30个交易日的日K线数据
    # 场景1:回测使用前复权价(默认)
    df_forward = qd.klines.get(
        "600519.SH", 
        period="1d", 
        count=30, 
        adjust="forward",  # 前复权-比例复权,适合计算收益率
        to_dataframe=True
    )
    
    # 场景2:实盘使用原始价
    df_none = qd.klines.get(
        "600519.SH", 
        period="1d", 
        count=30, 
        adjust="none",     # 不复权,适合实盘信号生成
        to_dataframe=True
    )
    
    # 计算两种价格下的区间收益率
    if not df_forward.empty and not df_none.empty:
        ret_forward = (df_forward['close'].iloc[-1] / df_forward['close'].iloc[0] - 1) * 100
        ret_none = (df_none['close'].iloc[-1] / df_none['close'].iloc[0] - 1) * 100
        
        print(f"前复权价区间收益率: {ret_forward:.2f}%")
        print(f"原始价区间收益率:   {ret_none:.2f}%")
        print(f"差异:               {ret_forward - ret_none:.2f} 个百分点")
        print("\n⚠️ 若差异显著,说明区间内存在除权除息事件,回测必须使用复权价!")
    else:
        print("⚠️ 数据为空,请检查 API Key 或网络连接")
        
except Exception as e:
    print(f"请求失败: {e}")
    print("请前往 https://quantdash.net/dashboard/keys/ 获取免费 Key")

复权参数速查表(基于 QuantDash 官方文档):

adjust 参数值说明适用场景
forward前复权 - 比例复权(默认)回测收益率计算(推荐)
backward后复权 - 比例复权观察长期价格走势
forward_additive前复权 - 差值复权观察绝对价差
backward_additive后复权 - 差值复权观察绝对价差
none不复权实盘信号生成与订单执行

四、性能优化与量化进阶避坑指南

避坑一:切勿在实盘信号生成中使用复权价。 实盘交易时,券商系统接收的是原始价订单。如果策略信号基于复权价计算,而实际成交价是原始价,两者之间可能存在系统性偏差。正确做法是:回测用 adjust="forward" 计算收益率和评估策略表现,实盘信号生成用 adjust="none" 获取原始价计算技术指标。

避坑二:警惕“未来函数”陷阱。 部分开发者使用除权因子进行后复权计算时,无意中引入了未来信息——因为在回测的时间点,未来的除权事件尚未发生。QuantDash 的服务器端复权严格基于历史除权因子,确保不会引入未来函数。

避坑三:利用本地 Parquet 缓存加速回测。 对于高频回测场景,建议将历史数据缓存为 Parquet 格式,避免重复网络请求:

import pandas as pd

# 首次获取后缓存
df = qd.klines.get("600519.SH", period="1d", count=500, adjust="forward", to_dataframe=True)
df.to_parquet("600519_SH_forward.parquet")

# 后续回测直接从本地读取
df_cached = pd.read_parquet("600519_SH_forward.parquet")

五、常见问题解答

Q1: 回测时应该用前复权还是后复权?

A: 回测计算收益率应使用前复权(adjust="forward"。前复权以最新价格为基准调整历史价格,使得历史收益率计算不受除权除息事件干扰,能真实反映策略的历史表现。后复权适合观察股票的长期价格走势,但不适合收益率计算。QuantDash 默认即为前复权,开发者无需额外配置。

Q2: 实盘交易中,技术指标(如均线、MACD)应该用复权价还是原始价计算?

A: 实盘信号生成应使用原始价(adjust="none"。技术指标的计算应基于实际可交易的价格,而实盘成交价是原始价。如果使用复权价计算指标,可能导致买入/卖出信号与实际可执行价格产生偏差。建议回测阶段用复权价评估策略,实盘阶段切换到原始价执行。

Q3: QuantDash 的复权数据更新频率如何?除权除息日当天能获取到正确的复权数据吗?

A: QuantDash 在除权除息日当日即完成复权因子更新,开发者无需手动维护除权因子表。通过 qd.klines.ex_factors() 接口可查询历史除权因子明细,便于审计和验证。


🔗 相关资源与延伸阅读

🚀 QuantDash 官网:https://quantdash.net/

📖 官方 Python SDK 文档:https://docs.quantdash.net/

⭐ GitHub 开源仓库:https://github.com/quantdash-net/QuantDash (欢迎 Star / Fork)

💡 获取免费 API Key 体验全量数据:https://quantdash.net/dashboard/keys/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值