Skip to content

因子 - 计算方法详解

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)/3
HML = (S/H + B/H)/2 - (S/L + B/L)/2
ff3 = calculate_factor_returns(
"ff3",
**inputs,
method="classic",
)

各模型 CLASSIC 分组配置

模型排序维度分组
FF3size(50%), bm(30%/70%)2x3
FF5size(50%), bm(30%/70%), op(30%/70%), inv(30%/70%)2x3x3x3
Carhartsize(50%), bm(30%/70%), momentum(30%/70%)2x3x3
HXZsize(50%), asset_growth(30%/70%), roe(30%/70%)2x3x3
SY4size(50%), mgmt(20%/80%), perf(20%/80%)2x5x5

日频 vs 月频

月频/日频在 load_ts_factor_inputsperiod 参数选择:"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)

数据过滤

计算过程中自动执行:

  1. 收益过滤:排除 return <= -1return >= 10 的异常值
  2. 缺失值处理:NA 值归入 “low” 组
  3. 最小股票数:单日可用股票 < 20 只时跳过
  4. 财报匹配:仅使用 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_inputssymbols 参数限定范围(省略时默认全市场):

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)