IC计算-前向/远期收益计算和代码示例

前向/远期收益通常用于因子挖掘、回测系统或机器学习预测模型的标签生成环节。

前向/远期收益必须与因子值在时间上严格错位,否则会造成未来数据泄漏。

这里尝试示例前向/远期收益的计算,以及背后隐藏的金融原理。

1 前向收益

1.1 前向收益

前向收益即远期收益表(Forward Returns),行为日期(t),列为股票代码(i)。

单元格为对应日期买入后、持有N日的未来收益(如t+1日收盘价/t日收盘价 - 1)。

需要注意的是

远期收益必须与因子值在时间上严格错位,

比如因子值用t日信息,收益用 t+1 或 t+5 日数据,

否则会造成未来数据泄漏。

1.2 代码示例

以下compute_forward_returns是前向收益的经典计算实现。

输入参数说明如下:

1)prices

要求为 DataFrame,索引(Index)为时间戳(Datetime),列(Columns)为股票代码(Ticker)。

这是量化研究中最标准的宽表(Panel Data)结构。

2)horizon

持有期,默认设为 20,通常指 20个交易日,约等于 1 个自然月。

返回参数说明如下:

形状与原DataFrame一致的收益率矩阵。

需要注意的是,最后 horizon 行数据会变成 NaN,因为未来价格不存在。

在实际使用前通常需要 .dropna()。

复制代码
# ──────────────────────────────────────────────────────────
# Forward returns
# ──────────────────────────────────────────────────────────

def compute_forward_returns(
    prices: pd.DataFrame,
    horizon: int = 20,
) -> pd.DataFrame:
    """
    Compute forward returns (t+1 to t+horizon).

    Returns
    -------
    DataFrame (datetime x stock) of forward returns.
    """
    return prices.shift(-horizon) / prices - 1

1.3 核心计算

前向收益的核心计算为:

prices.shift(-horizon) / prices - 1

1)shift(-horizon)

shift(-horizon)将价格数据整体向上平移N行。

这意味在时间点t,我们能取到未来t+horizon时刻的价格。

2) 除法与减一

计算的是简单收益率(Simple Return),即。

2 背后知识

2.1 持有期收益率

持有期收益率(Holding Period Return, HPR)

这是衡量投资在特定时间段内总回报的最基本指标。

代码计算的是非年化、绝对的区间收益。

如果 horizon=20,它代表的是未来一个月的绝对涨跌幅。

2.2 时间维度设定

时间维度设定,20 = 交易月

金融学实证研究表明,比如Fama-French 三因子模型,

月度频率(20~22个交易日)是去除微观市场噪音与捕捉中期动量效应的经典周期。

相比于日频数据,月频数据更能反映基本面信息。

2.3 前向 vs 后向

从前向(forward-looking)与后向(Backward-looking)的区别角度看:

这里代码计算的是前向收益,Forward Returns,即站在当下看未来,对应重要金融实务原则:

在实盘交易或建模时,前向收益绝对不能在信号产生之前执行,否则会引入前视偏差

从量化建模角度:

这行代码生成的forward_returns通常是因变量(Y/Label),

而prices中的历史截面数据(如 PE、PB、动量)则是自变量(X/Features)。

2.4 价格类型的隐含假设

从调整价 vs 原始价的角度看,代码直接使用了prices,应该是调整价。

在专业金融计算中,这里的prices必须是后复权价格(Adjusted Close Price),而非原始收盘价。

股票分红(Dividend)、送转股(Stock Split)会导致价格出现非市场性的缺口(Ex-Dividend Drop)。

如果使用未复权价格计算,会严重低估实际收益。

比如,分红1元,股价除息下跌1元,但投资者账户里多出了现金。

因此,复权价格保证了收益率连续性,使得计算出收益率等同于持有并再投资的总收益近似值。

2.5 简单收益率 vs 对数收益率

代码使用了简单收益率。

在截面(Cross-section)比较中,比如比较100只股票下个月谁涨得最多,

简单收益率具有可加性,即组合收益率是个股权重的加权平均。

缺点是时间不可加,如果要计算2个月的收益,需要做 (1+R1)(1+R2)-1,而非直接相加。

若想计算对数收益率,应改为

np.log(prices.shift(-horizon) / prices)

但这样会丧失截面加权的便利性。

reference


alphalens

https://github.com/quantopian/alphalens

RQFactor用户指南

https://www.ricequant.com/doc/rqfactor/manual/index-rqfactor

多因子模型中如何计算信息系数IC的时间序列

https://blog.csdn.net/liliang199/article/details/164300054

相关推荐
程序员果子4 分钟前
本体构建方法
人工智能·python·知识图谱·agent框架·本体
老秦包你会21 分钟前
计算机网络第二课 ----Socket(套接字)编程预备
开发语言·计算机网络·php
旖旎夜光23 分钟前
【C++ 基础入门】C++多态(下):单/多继承虚表、多态补充与 21 道高频题
开发语言·c++·笔记·学习
天天被压力32 分钟前
【A股分钟级高频数据完全手册 #11】券商实时行情数据接口:实时交易(券商源)接入与字段
java·人工智能·python
总裁余(余登武)37 分钟前
【python项目】:1操作EXCEl自动化开发
python·自动化·excel
芝梵家电数据笔记40 分钟前
用字段表核对暖菜板长期使用条件:结构、暖区、质保边界
python·家电·数据校验·dataclass·选购
天天被压力1 小时前
【A股分钟级高频数据完全手册 #12】股票五档盘口数据接口:买卖五档实时盘口解析
java·人工智能·python
Wang's Blog10 小时前
Java 项目实战: 交友项目 - FastDFS:入门案例
java·开发语言·交友
apcipot_rain11 小时前
C++转Java日记(03)
java·开发语言·c++
布莱克60511 小时前
C++ 中 map 的 insert 与 emplace:key 已存在时会覆盖吗?
开发语言·数据结构·c++·算法·map