← 返回《初阶量化交易:策略编写及系统搭建》
📑 查看全课大纲(第 24 / 38 节)

实现低PE策略的回测(2)

约 22 分钟

📺 正在播放小象官方高清录播(支持倍速与清晰度调节)

实现低PE策略的回测(二):除权调整与净值曲线生成

小象实战讲义 · 初阶量化交易:策略编写及系统搭建 本讲义仅用于编程与量化方法教学,不构成任何投资建议。

在完成了择时信号与开盘撮合逻辑后,量化回测系统面临的最后一道核心工程难题在于:持仓股票的除权除息(Corporate Actions)处理与真实账户资产净值(Equity Curve)的精准核算。除权除息必须区分两类公司行动:送转股(10 送 X / 10 转 X)需按市值守恒折算持仓股数;现金分红(10 派 Y 元)则股数不变、派现金额计入现金账户。若回测引擎未能正确处理——送股时不调股数,持仓市值将在除权当日凭空暴跌,造成虚假巨额回撤;派息时误用股数折算公式,持仓股数将被凭空放大,造成资产虚增。

本讲系统讲解基于市值守恒原理的盘前持仓除权除息股数修正算法;详细拆解每日收盘资产净值核算、累计收益率与沪深 300 基准收益率的对比方法;并对第三章从数据采集、因子清洗、股票池构建到撮合回测的全系统工程流水线进行大串联与总结


💡 核心导读

  • 持仓股除权除息的两类公司行动处理
    • 送转股(10 送 X / 10 转 X)——市值守恒,折算股数Position Value=Closet1×Sharest1=PreCloset×Sharest\text{Position Value} = Close_{t-1} \times Shares_{t-1} = PreClose_t \times Shares_t Sharest=int(Sharest1×Closet1PreCloset)Shares_t = \text{int}\left( Shares_{t-1} \times \frac{Close_{t-1}}{PreClose_t} \right) 注:若发生 10 送 10,股价由 20 元降为 10 元,持股数由 5,000 股自动修正为 10,000 股,总市值恒定为 10 万元。
    • 现金分红(10 派 Y 元)——股数不变,派现入现金账户Sharest=Sharest1,Casht=Casht1+Sharest1×Y10Shares_t = Shares_{t-1}, \qquad Cash_t = Cash_{t-1} + Shares_{t-1} \times \frac{Y}{10} 注:10 派 10 即每股派现 1 元,前收价由 20 元降为 19 元;股票市值减少的部分以现金形式回到账户,总资产(税前)守恒。若对派息误用送转的股数折算公式,5,000 股将被凭空放大为约 5,263 股,回测资产严重虚增。
  • 资产净值时序(Equity Curve)核算规范
    • 每日收盘总资产Total Equityt=Casht+iHoldings(Sharesi,t×Closei,t)\text{Total Equity}t = \text{Cash}t + \sum{i \in \text{Holdings}} (Shares{i, t} \times Close_{i, t})
    • 策略累计收益率Returnt=Total EquitytInitial CashInitial Cash×100%\text{Return}_t = \frac{\text{Total Equity}_t - \text{Initial Cash}}{\text{Initial Cash}} \times 100%
  • 第三章全系统工程链路大闭环
    1. 数据层Tushare 行情 + 东财财报爬虫入库 MongoDB;
    2. 清洗层daily_fixing 补齐停牌断点并计算前收价;
    3. 选股层stock_pool 筛选 0<PE<300 < PE < 30 标的,7 日动态调仓;
    4. 择时层:10 日均线金叉死叉判定;
    5. 撮合层:盘前除权调整 \to 开盘撮合买卖 \to 盘后结算净值。
┌─────────────────────────────────────────────────────────────┐
│                    量化交易系统全流程闭环总览                 │
└──────────────────────────────┬──────────────────────────────┘

 ┌───────────────┬─────────────┴─────────────┬───────────────┐
 ▼               ▼                           ▼               ▼
┌─────────────┐ ┌─────────────┐             ┌─────────────┐ ┌─────────────┐
│ 1. 数据工程 │ │ 2. 因子选股 │             │ 3. 择时信号 │ │ 4. 回测引擎 │
├─────────────┤ ├─────────────┤             ├─────────────┤ ├─────────────┤
│ • 行情/财报 │ │ • 0<PE<30   │             │ • 10日均线  │ │ • 除权修正  │
│ • 停牌清洗  │ │ • 7日调仓   │             │ • 边沿金叉  │ │ • 净值曲线  │
└─────────────┘ └─────────────┘             └─────────────┘ └─────────────┘

一、持仓除权修正与分红派息的工程细节

在每日 09:15 集合竞价前,回测引擎必须自动执行持仓扫描:

  1. 获取今日前收价:从 daily 集合中查询持仓股当天的 pre_close
  2. 比对昨日收盘价:若 PreClosetCloset1PreClose_t \ne Close_{t-1},表明发生除权除息;
  3. 判定公司行动类型:查询分红方案数据(如 Tushare 分红送股接口),区分送转股与现金分红——二者处理方式截然不同,不可混用;
  4. 送转股:等市值折算股数:按 Closet1/PreClosetClose_{t-1} / PreClose_t 比例重新计算持股数量,消除除权造成的市值断裂;
  5. 现金分红:股数不变,派现入账:将 Shares×\text{Shares} \times 每股派息计入现金账户,股票市值下降与现金增加相互抵消,总资产守恒。(红利税按持股期限差异化征收:持股超 1 年免征,1 个月至 1 年 10%,不足 1 个月 20%;教学回测可先按税前简化,实盘需在结算层扣除。)

二、净值曲线绘制与基准对比

回测输出的核心成果是一张资产净值随时间演变的收益曲线图(Equity Curve):

  • Alpha(超额收益):低 PE 选股 + 均线择时能否持续跑赢同期大盘指数(如沪深 300);
  • Beta 与回撤控制:在市场暴跌周期中,均线死叉与股票池调出能否及时将仓位变现,实现净值走平或微亏。

📝 动手练一练

下面我们用 Python 编写一段 持仓除权除息自动调整与市值守恒核验脚本,验证在 10 送 10 的高送转事件中,回测系统能否实现持仓股数自动由 5,000 股增至 10,000 股与市值的 100% 精确守恒:

import pandas as pd
import numpy as np

def test_corporate_action_and_equity():
    """
    演示回测系统中持仓除权除息股数自动修正与真实资金净值计算
    市值守恒公式: Shares_new = Shares_old * (Close_old / PreClose_new)
    """
    initial_cash = 100000.0
    shares = 5000  # 初始持有 5000 股
    cash = 0.0
    
    # 模拟发生 10 送 10 除权除息事件 (股价由 20.0 元跳空至 10.0 元)
    close_prev = 20.0        # 昨日收盘价
    pre_close_curr = 10.0    # 今日开盘参考前收价
    
    # 1. 盘前根据市值守恒定律修正持股数量
    adjusted_shares = int(shares * (close_prev / pre_close_curr))
    
    # 2. 市值核验
    val_before = shares * close_prev
    val_after = adjusted_shares * pre_close_curr
    
    print("================ 持仓除权除息自动调整与市值守恒 ================")
    print(f"除权前持股数: {shares} 股, 前收盘价: {close_prev} 元 -> 市值: {val_before:.2f} 元")
    print(f"除权后持股数: {adjusted_shares} 股, 前收价: {pre_close_curr} 元 -> 市值: {val_after:.2f} 元")
    print(f"市值守恒核验: {'100% 守恒无偏差' if val_before == val_after else '存在偏差'}")
    print("==============================================================")

if __name__ == "__main__":
    test_corporate_action_and_equity()

运行结果输出:

================ 持仓除权除息自动调整与市值守恒 ================
除权前持股数: 5000 股, 前收盘价: 20.0 元 -> 市值: 100000.00 元
除权后持股数: 10000 股, 前收价: 10.0 元 -> 市值: 100000.00 元
市值守恒核验: 100% 守恒无偏差
==============================================================

本章小结

  1. 区分两类除权除息处理:送转股利用 Closet1/PreClosetClose_{t-1} / PreClose_t 比例动态折算持仓股数(市值守恒),现金分红保持股数不变、派现计入现金账户(总资产守恒);对派息误用股数折算会凭空放大持仓,是回测资产失真的高频 Bug。
  2. 标准净值结算时序:以收盘价核算每日持仓市值,生成规范的资产净值曲线与相对基准收益率。
  3. 完成全系统大贯通:第三章成功打通了数据获取、清洗对齐、因子选股、择时注入与撮合回测的全套轻量级量化交易系统。

📋 行动清单 (Action Checklist)

  • 运行本讲除权修正代码,验证持仓股数与市值的动态守恒过程;
  • 整合第三章所学模块,在本地运行一次完整的低 PE 策略年度历史回测;
  • 预习第四章《仓位管理和风险控制功能实现》,探索如何通过资金管理实现长期稳健生存。

— 小象教研组

配套学习资源与课件
  • 第3章课件:上手搭建最简单的交易系统(PDF · 3.8MB)
    下载
  • 开发环境准备:软件安装指导(PDF · 0.9MB · 建议第3章动手实践前先通读)
    下载
  • 量化入门推荐书单(PDF · 318KB)
    下载
🎁 免费学习资源

领取《小象 11GB VIP 课件资料包与大厂真题手册》

包含全套实战 Jupyter 源码、清洗后数据集、大厂高频面试真题与专属学员答疑交流群。

  • 完整 Python / 数据分析 Jupyter 实战源码
  • 大厂真实业务数据集与练习题
  • 微信扫码添加课程顾问,免费获取网盘下载链接
微信二维码:扫码添加课程顾问微信扫码添加顾问