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

相关推荐
2601_962381861 小时前
python安装好了如何设置环境变量
python·开发工具·环境变量·虚拟环境·ide配置
小溪学编程1 小时前
Java ListIterator 接口详解:双向遍历与列表修改的利器
java·开发语言·windows
影视飓风TIM1 小时前
C++11 新特性:Lambda表达式、std::function与std::bind
开发语言·c++
sbjdhjd1 小时前
在 8 字符、字母数字过滤与 PHP 版本差异下复盘临时文件命令执行链 | (8字符绕过)
android·java·开发语言·安全·web安全·数据挖掘·php
小柯南敲键盘1 小时前
跨马翻译:跨境电商图片翻译工具,批量处理视频字幕与抠图
python·音视频
Hali_Botebie1 小时前
PyTorch 内存布局,.view()要合并哪两个维度(比如 B 和 G),这两个维度在内存里就必须“紧挨着”。
人工智能·pytorch·python
统计学小王子2 小时前
数学建模国赛倒计时 1 天 ——《统计模型精讲(逐步回归 R 语言实战篇)》
开发语言·数学建模·r语言
用户019027581612 小时前
如何用 Python 算多只股票的相关性矩阵与组合波动率?
python
ttwuai2 小时前
Go 后台接入单点登录后,JWT、菜单权限和接口 403 怎么验?
开发语言·后端·golang