摘要
本笔记记录多因子选股模型中常见因子的构造方法、盈利逻辑及失效条件,涵盖估值因子、动量因子和反转因子。
因子构造
估值因子(EP)
\[ EP_t = \frac{Earnings_t}{MarketCap_t} \]
动量因子
\[ Mom_{12,1} = \frac{P_{t-1}}{P_{t-12}} - 1 \]
因子合成
加权方式采用等权合成与ICIR加权两种方式:
\[ Score_i = \sum_{k=1}^K w_k \cdot Rank(F_{k,i}) \]
其中 \(w_k\) 为因子权重,\(Rank(\cdot)\) 为横截面排序分位数。
因子测试代码
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 模拟因子数据
np.random.seed(42)
n_stocks = 1000
n_periods = 252
dates = pd.date_range('2023-01-01', periods=n_periods, freq='D')
factor = np.random.randn(n_stocks)
returns = 0.05 * factor + np.random.randn(n_stocks) * 0.02
# IC 计算
ic = np.corrcoef(factor, returns)[0, 1]
print(f"Rank IC: {ic:.4f}")
# 分组收益
groups = pd.qcut(factor, 5, labels=['Q1(低)', 'Q2', 'Q3', 'Q4', 'Q5(高)'])
group_returns = pd.Series(returns, index=groups).groupby(level=0).mean()
fig, ax = plt.subplots(figsize=(8, 4))
colors = ['#c96442', '#e8927a', '#f0c4a0', '#a8c4d8', '#5a8a9a']
bars = ax.bar(group_returns.index, group_returns.values, color=colors)
ax.set_title('多空组合收益(示例)')
ax.set_ylabel('日均收益 (%)')
ax.axhline(0, color='gray', linestyle='--', linewidth=0.5)
plt.tight_layout()
plt.show()
/tmp/ipykernel_2508/3113493769.py:28: UserWarning: Glyph 20302 (\N{CJK UNIFIED IDEOGRAPH-4F4E}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/tmp/ipykernel_2508/3113493769.py:28: UserWarning: Glyph 39640 (\N{CJK UNIFIED IDEOGRAPH-9AD8}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/tmp/ipykernel_2508/3113493769.py:28: UserWarning: Glyph 26085 (\N{CJK UNIFIED IDEOGRAPH-65E5}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/tmp/ipykernel_2508/3113493769.py:28: UserWarning: Glyph 22343 (\N{CJK UNIFIED IDEOGRAPH-5747}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/tmp/ipykernel_2508/3113493769.py:28: UserWarning: Glyph 25910 (\N{CJK UNIFIED IDEOGRAPH-6536}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/tmp/ipykernel_2508/3113493769.py:28: UserWarning: Glyph 30410 (\N{CJK UNIFIED IDEOGRAPH-76CA}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/tmp/ipykernel_2508/3113493769.py:28: UserWarning: Glyph 22810 (\N{CJK UNIFIED IDEOGRAPH-591A}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/tmp/ipykernel_2508/3113493769.py:28: UserWarning: Glyph 31354 (\N{CJK UNIFIED IDEOGRAPH-7A7A}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/tmp/ipykernel_2508/3113493769.py:28: UserWarning: Glyph 32452 (\N{CJK UNIFIED IDEOGRAPH-7EC4}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/tmp/ipykernel_2508/3113493769.py:28: UserWarning: Glyph 21512 (\N{CJK UNIFIED IDEOGRAPH-5408}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/tmp/ipykernel_2508/3113493769.py:28: UserWarning: Glyph 65288 (\N{FULLWIDTH LEFT PARENTHESIS}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/tmp/ipykernel_2508/3113493769.py:28: UserWarning: Glyph 31034 (\N{CJK UNIFIED IDEOGRAPH-793A}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/tmp/ipykernel_2508/3113493769.py:28: UserWarning: Glyph 20363 (\N{CJK UNIFIED IDEOGRAPH-4F8B}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/tmp/ipykernel_2508/3113493769.py:28: UserWarning: Glyph 65289 (\N{FULLWIDTH RIGHT PARENTHESIS}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/home/runner/.local/lib/python3.12/site-packages/IPython/core/pylabtools.py:158: UserWarning: Glyph 26085 (\N{CJK UNIFIED IDEOGRAPH-65E5}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
/home/runner/.local/lib/python3.12/site-packages/IPython/core/pylabtools.py:158: UserWarning: Glyph 22343 (\N{CJK UNIFIED IDEOGRAPH-5747}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
/home/runner/.local/lib/python3.12/site-packages/IPython/core/pylabtools.py:158: UserWarning: Glyph 25910 (\N{CJK UNIFIED IDEOGRAPH-6536}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
/home/runner/.local/lib/python3.12/site-packages/IPython/core/pylabtools.py:158: UserWarning: Glyph 30410 (\N{CJK UNIFIED IDEOGRAPH-76CA}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
/home/runner/.local/lib/python3.12/site-packages/IPython/core/pylabtools.py:158: UserWarning: Glyph 22810 (\N{CJK UNIFIED IDEOGRAPH-591A}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
/home/runner/.local/lib/python3.12/site-packages/IPython/core/pylabtools.py:158: UserWarning: Glyph 31354 (\N{CJK UNIFIED IDEOGRAPH-7A7A}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
/home/runner/.local/lib/python3.12/site-packages/IPython/core/pylabtools.py:158: UserWarning: Glyph 32452 (\N{CJK UNIFIED IDEOGRAPH-7EC4}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
/home/runner/.local/lib/python3.12/site-packages/IPython/core/pylabtools.py:158: UserWarning: Glyph 21512 (\N{CJK UNIFIED IDEOGRAPH-5408}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
/home/runner/.local/lib/python3.12/site-packages/IPython/core/pylabtools.py:158: UserWarning: Glyph 65288 (\N{FULLWIDTH LEFT PARENTHESIS}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
/home/runner/.local/lib/python3.12/site-packages/IPython/core/pylabtools.py:158: UserWarning: Glyph 31034 (\N{CJK UNIFIED IDEOGRAPH-793A}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
/home/runner/.local/lib/python3.12/site-packages/IPython/core/pylabtools.py:158: UserWarning: Glyph 20363 (\N{CJK UNIFIED IDEOGRAPH-4F8B}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
/home/runner/.local/lib/python3.12/site-packages/IPython/core/pylabtools.py:158: UserWarning: Glyph 65289 (\N{FULLWIDTH RIGHT PARENTHESIS}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
/home/runner/.local/lib/python3.12/site-packages/IPython/core/pylabtools.py:158: UserWarning: Glyph 20302 (\N{CJK UNIFIED IDEOGRAPH-4F4E}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
/home/runner/.local/lib/python3.12/site-packages/IPython/core/pylabtools.py:158: UserWarning: Glyph 39640 (\N{CJK UNIFIED IDEOGRAPH-9AD8}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)
数据一览
| 估值(EP) |
0.042 |
0.76 |
6.8% |
8%/月 |
| 动量(Mom) |
0.038 |
0.52 |
5.2% |
15%/月 |
| 反转(Rev) |
-0.035 |
-0.61 |
-4.1% |
25%/月 |
| 合成(等权) |
0.052 |
0.89 |
8.2% |
12%/月 |
失效条件
- 估值因子:在流动性紧缩期(如2020年3月),低估值股遭无差别抛售,EP因子失效
- 动量因子:在市场急跌反弹时(V型反转),动量因子出现大幅回撤
- 反转因子:在趋势市(单边上涨)中,反转因子持续亏损
- 合成因子:当各因子同时失效(如2021年核心资产抱团),多因子组合也难以避险
策略限制:以上为示例数据,实盘中需考虑交易成本、冲击成本、以及因子之间的相关性变化。