因子 - 计算方法详解
SIMPLE vs CLASSIC
| 维度 | SIMPLE(默认) | CLASSIC |
|---|---|---|
| 分组方法 | 中位数二分 | 分位数断点(如 30%/70%) |
| 组合加权 | 等权平均 | 市值加权 |
| 分组维度 | 单变量独立排序 | 多变量独立排序 (2x3 等) |
| 计算速度 | 快 | 较慢 |
| 学术严谨性 | 一般 | 接近学术论文实现 |
因子计算需要先准备符合 schema 的数据帧。最简方式是 load_ts_factor_inputs(),返回可直接传给 calculate_factor_returns() 的输入:
from jh_quant.factors import calculate_factor_returns, load_ts_factor_inputs
inputs = load_ts_factor_inputs( start_date="2020-01-01", end_date="2024-12-31", period="M",)SIMPLE 方法
每个因子按对应变量独立排序后二分(high / low):
smb = 小市值股票等权均值 - 大市值股票等权均值hml = 高 BM 股票等权均值 - 低 BM 股票等权均值ff3 = calculate_factor_returns( "ff3", **inputs, method="simple", # 默认值)CLASSIC 方法
以 FF3 CLASSIC 为例:
Size 分组: small(市值 <= 中位数)/ big(> 中位数)Value 分组: low (bottom 30%) / medium / high (top 30%)
6个交叉组合的市值加权收益率: S/L S/M S/H B/L B/M B/H
SMB = (S/L + S/M + S/H)/3 - (B/L + B/M + B/H)/3HML = (S/H + B/H)/2 - (S/L + B/L)/2ff3 = calculate_factor_returns( "ff3", **inputs, method="classic",)各模型 CLASSIC 分组配置
| 模型 | 排序维度 | 分组 |
|---|---|---|
| FF3 | size(50%), bm(30%/70%) | 2x3 |
| FF5 | size(50%), bm(30%/70%), op(30%/70%), inv(30%/70%) | 2x3x3x3 |
| Carhart | size(50%), bm(30%/70%), momentum(30%/70%) | 2x3x3 |
| HXZ | size(50%), asset_growth(30%/70%), roe(30%/70%) | 2x3x3 |
| SY4 | size(50%), mgmt(20%/80%), perf(20%/80%) | 2x5x5 |
日频 vs 月频
月频/日频在 load_ts_factor_inputs 的 period 参数选择:"M" 直接使用 TS_MONTHLY_* 月频行情与 TS_MONTHLY_BASIC 月度基本面;"D" 使用日频行情并转换为月末收益:
# 月度因子(基本面使用 TS_MONTHLY_BASIC)inputs_m = load_ts_factor_inputs( start_date="2020-01-01", end_date="2024-12-31", period="M",)ff3_m = calculate_factor_returns("ff3", **inputs_m)
# 日度因子(日频行情转月末收益)inputs_d = load_ts_factor_inputs( start_date="2020-01-01", end_date="2024-12-31", period="D",)ff3_d = calculate_factor_returns("ff3", **inputs_d)| 方面 | 月频 | 日频 |
|---|---|---|
| 数据量 | ~120个月/10年 | ~2500日/10年 |
| 计算速度 | 快 | 较慢 |
| 噪音 | 较低 | 较高 |
| 适用场景 | 资产定价研究 | 高频回测 |
性能优化
Polars 加速
# 启用 Polars(默认)ff5 = calculate_factor_returns("ff5", **inputs, use_polars=True)
# 禁用(使用纯 pandas)ff5 = calculate_factor_returns("ff5", **inputs, use_polars=False)并行任务数
# 自动检测(默认,最多 4 核)ff3 = calculate_factor_returns("ff3", **inputs)
# 单线程(调试用)ff3 = calculate_factor_returns("ff3", **inputs, n_jobs=1)
# 指定核数ff3 = calculate_factor_returns("ff3", **inputs, n_jobs=8)数据过滤
计算过程中自动执行:
- 收益过滤:排除
return <= -1或return >= 10的异常值 - 缺失值处理:NA 值归入 “low” 组
- 最小股票数:单日可用股票 < 20 只时跳过
- 财报匹配:仅使用
ann_date已知且不超过 6 个月的财报数据
无风险利率
框架支持传入 SHIBOR 作为无风险利率(用于计算超额收益):
ff3 = calculate_factor_returns( "ff3", **inputs, risk_free_rate=shibor, # JHData().get_data(DataTypes.TS_SHIBOR, ...) 的返回)- 月度计算:使用 1 个月期 SHIBOR,转为月度利率(TS_SHIBOR 列名
f_1m,即rf = f_1m / 100 / 12) - 日度计算:使用隔夜 SHIBOR,转为日度利率(TS_SHIBOR 列名
on,即rf = on / 100 / 360)
数据源统一用 tushare 的
TS_SHIBOR(akshare 的 SHIBOR 接口已不再更新)。 列名兼容:传DataTypes.TS_SHIBOR的原始返回(date/on/f_1m/...)即可;旧 akshare 列名on_rate/m1_rate也仍被识别。
限定标的范围
通过 load_ts_factor_inputs 的 symbols 参数限定范围(省略时默认全市场):
inputs = load_ts_factor_inputs( start_date="2020-01-01", end_date="2024-12-31", symbols=["000001.SZ", "000002.SZ", "600519.SH"],)
ff3 = calculate_factor_returns("ff3", **inputs)