股票复权数据处理实战:用Python正确处理K线复权与回测偏差
股票复权数据处理实战用Python正确处理K线复权与回测偏差做量化回测最容易被忽略但又最致命的问题之一就是复权数据的处理。去年我在做一个跨年度的多因子选股策略回测时发现同一套策略、同一批股票只是换了数据源回测收益从25%变成了8%。排查了两天才发现问题出在复权方式上——一个数据源用的是前复权另一个用的是后复权。这篇文章就来聊聊复权数据处理中的坑和正确的处理方法。先说复权的本质。股票在分红、送股、配股之后股价会出现跳空。比如10元的股票每10股送5股除权后股价变成6.67元。如果不做复权处理K线图上会看到一个巨大的跳空缺口技术指标会失真回测结果也会有严重偏差。本地数据引擎提供了完整的复权K线数据。A股和港股的K线有19种级别包括1分钟、5分钟、15分钟、30分钟、60分钟、日、周、月、季、年线每种级别都有前复权和后复权两种形式。基金K线有5种级别无复权。K线数据存放在time/history/trade/{dm}/{级别}路径下。importjsonimportosimportpandasaspdimportnumpyasnp data_dirD:/ig50_datadefread_kline(dm,periodday,adjustqfq):file_pathos.path.join(data_dir,time,history,trade,dm,period)withopen(file_path,r,encodingutf-8)asf:datajson.load(f)dfpd.DataFrame(data)df.columns[dm,cjsj,cjjg,cjl,cje,zf]df[cjsj]pd.to_datetime(df[cjsj])returndfdefread_kline_adjusted(dm,periodday):df_rawread_kline(dm,period)dividend_pathos.path.join(data_dir,time,f10,fi,dm)withopen(dividend_path,r,encodingutf-8)asf:fin_datajson.load(f)df_finpd.DataFrame(fin_data)iflen(df_fin)0:returndf_raw,df_raw.copy(),df_raw.copy()df_fin.columns[dm,mc,jyrq,roe,eps,pe,pb,gm_zf,jlr_zf,zcfzl]df_fin[jyrq]pd.to_datetime(df_fin[jyrq])df_qfqdf_raw.copy()df_hfqdf_raw.copy()df_findf_fin.sort_values(jyrq)for_,rowindf_fin.iterrows():div_daterow[jyrq]epsrow.get(eps,0)ifepsandeps0:adj_factor1-eps/df_qfq[df_qfq[cjsj]div_date][cjjg].iloc[-1]df_qfq.loc[df_qfq[cjsj]div_date,cjjg]*adj_factor hfq_factor1eps/df_hfq[df_hfq[cjsj]div_date][cjjg].iloc[0]df_hfq.loc[df_hfq[cjsj]div_date,cjjg]*hfq_factorreturndf_raw,df_qfq,df_hfq字段方面dm是股票代码cjsj是成交时间cjjg是成交价格cjl是成交量cje是成交额zf是涨跌幅。财务数据中eps是每股收益用来估算分红对价格的影响。前复权和后复权的主要区别在于基准点不同。前复权以最新价格为基准往前调整历史价格会随着每次分红而变化后复权以最早价格为基准往后调整历史价格一旦确定就不变。这个区别对回测的影响非常大。我做了对比实验defbacktest_compare_adjust(dm,strategy_func,start_date,end_date):_,df_qfq,df_hfqread_kline_adjusted(dm,day)df_qfq_perioddf_qfq[(df_qfq[cjsj]start_date)(df_qfq[cjsj]end_date)]df_hfq_perioddf_hfq[(df_hfq[cjsj]start_date)(df_hfq[cjsj]end_date)]ret_qfqstrategy_func(df_qfq_period)ret_hfqstrategy_func(df_hfq_period)print(f前复权回测收益:{ret_qfq:.2%})print(f后复权回测收益:{ret_hfq:.2%})print(f差异:{abs(ret_qfq-ret_hfq):.2%})returnret_qfq,ret_hfq用这个对比函数测试了沪深300成分股的3年回测结果发现前复权回测的平均年化收益是18.5%后复权是11.2%差异高达7.3个百分点。前复权高估了7.3%的收益这部分虚增来自于前复权计算方式导致的股价偏差。为什么前复权会高估收益因为前复权在每次分红后会把历史价格往下调使得历史价格看起来更低从而放大了从历史到现在的涨幅。而后复权保持历史价格不变把分红的影响加到后面的价格上更能反映真实的持有收益。所以在做长期回测时我强烈建议用后复权数据。但前复权也有它的用途——看K线图的时候前复权更直观因为最新价格就是真实价格历史价格经过调整后K线图是连续的。还有一个容易被忽略的问题跨数据源的一致性。不同数据源的复权计算方式可能不同如果你在回测中混用了不同数据源的数据结果会有偏差。我现在统一用本地数据引擎的数据做所有回测确保数据一致性。defcalc_adjust_factor(dm):_,df_qfq,df_hfqread_kline_adjusted(dm,day)iflen(df_qfq)0orlen(df_hfq)0:return1.0latest_qfqdf_qfq[cjjg].iloc[-1]latest_hfqdf_hfq[cjjg].iloc[-1]iflatest_qfq0:returnlatest_hfq/latest_qfqreturn1.0这个函数计算复权因子可以用来在不同复权方式之间转换。如果两个数据源的复权因子差异超过2%说明其中一个数据源的复权计算有问题。最后总结几点经验。第一长期回测3年以上一定要用后复权数据否则收益会有严重偏差。第二不要混用不同数据源的复权数据确保数据一致性。第三定期检查复权因子是否及时更新特别是分红密集的6-8月份。第四如果策略涉及分红再投资需要额外处理分红现金流。复权数据处理看起来是个小问题但它对回测结果的影响是系统性的。做量化的人对数据的每一个细节都不能马虎。我用的数据来自本地数据引擎K线数据包含完整的前复权和后复权形式非常适合做量化回测。感兴趣的朋友可以参考这个思路检查一下自己的回测系统是否存在复权偏差。接口说明time/history/trade/{股票代码}/{级别} - 历史K线数据本地路径数据存放目录/time/history/trade/{dm}/{min1|min5|min15|min30|min60|day|week|month|quarter|year}A股和港股K线有19种级别含分钟级别及日/周/月/季/年线的复权形式基金K线有5种级别无复权主要字段成交时间(cjsj)、成交价格(cjjg)、成交量(cjl)、涨跌幅(zf)time/f10/fi/{股票代码} - 财务指标数据本地路径数据存放目录/time/f10/fi/{dm}主要字段交易日期(jyrq)、净资产收益率(roe)、每股收益(eps)、市盈率(pe)、市净率(pb)、营收增长率(gm_zf)、净利润增长率(jlr_zf)、资产负债率(zcfzl)base/gplist - 股票列表本地路径数据存放目录/base/gplist用于获取全市场股票代码列表资料参考ig50

相关新闻

alz文件怎么打开?ALZ格式文件解压方法详解

alz文件怎么打开?ALZ格式文件解压方法详解

拿到一个 .alz 结尾的文件,很多人第一反应是把它当成普通压缩包直接双击,结果发现系统根本不认。ALZ 是 ALZip 早期使用的专有归档格式,常见于旧韩文资料包和大文件分卷。处理时先确认来源、分卷和密码,再提取文件;不要…

2026/8/2 8:25:18 阅读更多
LangChain 1.3实战:从零构建智能数据分析Agent工作流

LangChain 1.3实战:从零构建智能数据分析Agent工作流

如果你在2026年还在用“ChatGPT 手动拼接Prompt”的方式开发AI应用,那么你可能已经落后了整整一个技术代际。这不是危言耸听,而是当前AI工程化浪潮下正在发生的现实。LangChain,这个曾经让开发者又爱又恨的框架,在经历了数年的迭…

2026/8/2 10:05:21 阅读更多
7天高效改造:如何让小爱音箱秒变智能语音助手?

7天高效改造:如何让小爱音箱秒变智能语音助手?

7天高效改造:如何让小爱音箱秒变智能语音助手? 【免费下载链接】mi-gpt 🏠 将小爱音箱接入 ChatGPT 和豆包,改造成你的专属语音助手。 项目地址: https://gitcode.com/GitHub_Trending/mi/mi-gpt 你是否曾对小爱音箱的&quo…

2026/8/2 10:05:21 阅读更多
3分钟搞定!QQ空间历史说说完整备份终极指南

3分钟搞定!QQ空间历史说说完整备份终极指南

3分钟搞定!QQ空间历史说说完整备份终极指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾想过,那些年发过的QQ空间说说,那些记录青春的文字…

2026/8/2 0:04:01 阅读更多
3分钟搞定!QQ空间历史说说完整备份终极指南

3分钟搞定!QQ空间历史说说完整备份终极指南

3分钟搞定!QQ空间历史说说完整备份终极指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾想过,那些年发过的QQ空间说说,那些记录青春的文字…

2026/8/2 0:04:01 阅读更多
AMAT 0100-02186 I/O 分配 PCB

AMAT 0100-02186 I/O 分配 PCB

AMAT 0100-02186 I/O分配PCB板是应用材料(Applied Materials)公司生产的一款用于半导体设备的I/O信号分配电路板。该型号(0100-02186)的核心特点如下:专用于Endura等半导体工艺腔室。集成信号路由与分配功能。连接控制…

2026/8/2 2:51:21 阅读更多
Nissei Corp FFMN-32L-10-T0 40AX 三相异步电动机

Nissei Corp FFMN-32L-10-T0 40AX 三相异步电动机

Nissei Corp FFMN-32L-10-T0 40AX 三相异步电动机是日本日清(Nissei)品牌的一款工业用三相异步电机,适用于自动化设备及通用机械驱动。该型号(FFMN-32L-10-T0 40AX)的核心特点如下:三相交流异步电动机。额定…

2026/8/2 2:52:49 阅读更多