Week 2 周复盘 + 四因子相关性 + Week 3 准备
Week 2 周复盘 + 四因子相关性 + Week 3 准备
日期: 2026-05-23 方向: Week 2 复盘 阶段: Phase 1: 基础与工具链 标签: #WeeklyReview #FactorInvesting #Correlation #Diversification #Week3Prep
今日目标
| 类型 | 内容 |
|---|---|
| 复盘 | Week 2 (Day 8-13) 完成度自评 + 因子知识图谱串联 |
| 实操 | 把 Day 10-13 的四个 long-only 因子收益序列拉到一起,算 4×4 相关矩阵 |
| 反思 | 三个最重要的认知变化、本周潜在坑、当前因子能力分级 |
| 预告 | Week 3 期权基础 + Greeks (Day 15-21) |
| 产出 | TR-DAY14 笔记 + 四因子相关性热图 + 多因子合成的概念铺垫 |
一、Week 2 完成度自评
1.1 每日实操产出对照表
把 Day 8-13 应当产生的「实操产出」摆一起,用最严的标准自评。Week 1 复盘里我已经验证过这种「不允许日记式自我感觉良好」的盘点形式,Week 2 沿用。
| Day | 主题 | 应交付物 | 自评状态 | 备注 |
|---|---|---|---|---|
| Day 8 | Fama-French 三因子论文精读 | 从 Ken French 数据库加载 SMB/HML/MKT-RF/RF 月度数据 | 完成 | tr_lib/factors/ff_loader.py,缓存到 parquet |
| Day 8 | FF3 回归脚本 | 用 SMB/HML/MKT-RF 对任意标的回归得 alpha + 三因子载荷 | 完成 | 拿 SPY / AAPL / BRK-B 各回归一遍 sanity check |
| Day 9 | 单因子评估 | 写 IC / IR 函数,跑 alphalens 教程 | 完成 | tr_lib/factor_eval.py,IC / IR / IC decay / 分组回测全套齐了 |
| Day 9 | IC decay 可视化 | 5/10/20/60 日 forward return 的 IC 衰减曲线 | 完成 | 在动量因子上跑过,T+1 IC 最高、T+60 几乎归零 |
| Day 10 | 动量因子 | 12-1 月 momentum,月度截面,long top decile | 完成 | S&P 500 universe 2014-2024,annualized return ≈ 14.8%,Sharpe ≈ 0.72 |
| Day 10 | momentum crash 复现 | 找 2009 反弹 / 2020 COVID 反弹这两个动量崩盘期 | 部分完成 | 2020 COVID 反弹复现成功(一个月 -22%),2009 数据 Ken French 给出但我自己 universe 太短没复现 |
| Day 11 | 价值因子 | B/M、E/P、CF/P 单独跑 + 等权合成 | 完成 | annualized return ≈ 9.1%,Sharpe ≈ 0.41,比预期弱很多 |
| Day 11 | PIT 数据问题排查 | 用 announcement date 而不是 fiscal date 对齐 | 部分完成 | 我用了 fiscal end + 90 天 lag 近似,没拿到真实 announcement date — 这是已知 bias |
| Day 12 | 低波动因子 | 12 个月 trailing daily return std 排序,bottom decile long | 完成 | annualized return ≈ 10.2%,Sharpe ≈ 0.79,Sharpe 反超 momentum |
| Day 12 | 行业偏向分析 | low-vol 组合的 GICS sector 分布 | 完成 | Utilities + Consumer Staples + Healthcare 占比 56%(验证经典文献结论) |
| Day 13 | 质量因子 (QMJ 简化版) | profitability + safety 两个组件(payout/growth 因 yfinance 数据缺简化) | 完成 | annualized return ≈ 11.4%,Sharpe ≈ 0.65 |
| Day 13 | 行业中性化 | 在 sector 内做排名 z-score | 未完成 | 知道方法论,但 universe 内每个 sector 只有 30-50 支股,分位数样本太少;Week 5 多因子时再补 |
1.2 完成度评分
应交付物总数:12
已完成:9
部分完成:2(动量崩盘历史数据、PIT 数据近似)
未完成:1(行业中性化)
Week 2 完成度:75% (9/12)
含部分完成的「至少摸过」率:92% (11/12)
自我评估:可接受。未完成的「行业中性化」是有意推迟的——动机是 Day 13 我意识到「单因子做行业中性化没问题,但样本量小会让分位数排序失真」,与其做错不如等 Week 5 多因子框架时统一处理。这种有意识的推迟和 Week 1 那种「速度 vs 严谨度的偷懒」性质不同。
PIT 数据这一项是真的有 bias 在结果里,我必须诚实记下:Day 11 价值因子 Sharpe 0.41 这个数字本身可能高估了 5-10%(fiscal end + 90 天近似偏乐观,因为真实 announcement 通常 45-60 天,这意味着 lookahead 风险更小但同时数据也更少)。Phase 2 接 Polygon / Compustat 这类有真实 announcement date 的数据源时再校准。
1.3 文档/代码资产盘点
| 资产 | 路径 | 状态 |
|---|---|---|
| 6 篇日记 | docs/daily/TR-DAY{8..13}.md | ✓ |
| 进度文件 | docs/daily/TR_PROGRESS.md | ✓ Week 2 标 ✅ |
| Ken French 数据加载 | tr_lib/factors/ff_loader.py | ✓ 缓存到 parquet |
| FF3 回归脚本 | tr_lib/factors/ff3_regress.py | ✓ |
| 因子评估工具集 | tr_lib/factor_eval.py (IC/IR/decay/quantile) | ✓ |
| 动量因子 | tr_lib/factors/momentum.py | ✓ |
| 价值因子 | tr_lib/factors/value.py | △ PIT 用近似 |
| 低波动因子 | tr_lib/factors/low_vol.py | ✓ |
| 质量因子 | tr_lib/factors/quality.py | △ 简化版 QMJ |
| 月度收益序列 | data/factor_returns/{momentum,value,low_vol,quality}.parquet | ✓ |
关键基础设施:四个因子的月度 long-only 收益序列都已经持久化到 parquet。这是今天能做相关性分析的前提——不用每次重新跑回测。
二、Week 2 知识图谱
把 6 天的核心概念串起来,看清「理论 → 评估方法 → 四大因子 → 组合」的依赖链。孤立的因子知识不构成能力,看到节点之间的依赖才算「真懂」。
2.1 因子研究的全链路
[DAY 8]
┌──────────────────────┐
│ Fama-French 三因子 │
│ ─ Market (MKT-RF) │
│ ─ Size (SMB) │
│ ─ Value (HML) │
│ ─ 风险 vs 行为解释 │
│ ─ 五因子扩展 (RMW/CMA)│
└──────────┬───────────┘
│
[DAY 9]
┌──────────▼───────────┐
│ 单因子评估方法论 │
│ ─ IC (rank/Pearson) │
│ ─ IR = mean(IC)/std │
│ ─ IC decay 曲线 │
│ ─ Quantile spread │
│ ─ 陷阱:look-ahead / │
│ PIT / survivorship │
└──────────┬───────────┘
│
┌────────────────┼────────────────┐
│ │ │
[DAY 10] [DAY 11] [DAY 12] [DAY 13]
┌───────▼────┐ ┌──────────▼─────┐ ┌──────▼──────┐ ┌──────▼─────┐
│ Momentum │ │ Value │ │ Low Vol │ │ Quality │
│ 12-1 月 │ │ B/M E/P CF/P │ │ 12M std │ │ QMJ 4 组件 │
│ 截面排序 │ │ Asness 跨资产 │ │ BAB │ │ profit │
│ Top decile │ │ 失落十年争议 │ │ 行业偏向 │ │ growth │
│ ───────── │ │ ───────── │ │ ───────── │ │ safety │
│ Crash risk │ │ PIT 数据问题 │ │ 利率敏感 │ │ payout │
│ Vol-scale │ │ Value Trap │ │ 2022 失效 │ │ Quality ETF│
└─────┬──────┘ └────────┬───────┘ └──────┬──────┘ └──────┬─────┘
│ │ │ │
└─────────┬────────┴────────────────┴────────────────┘
│
[DAY 14 = TODAY]
┌─────────▼──────────────────┐
│ 4 因子相关性矩阵 + 多因子组合 │
│ ─ Correlation matrix │
│ ─ Equal-weight │
│ ─ IC-weight (Day 9 复用) │
│ ─ Risk Parity (概念) │
│ → Week 5 正式做组合 │
└────────────────────────────┘
2.2 用一个表概括 Week 2 主链路
| 层级 | 关注什么 | 关键概念 | 失败模式 |
|---|---|---|---|
| 理论层 | 因子为什么有 risk premium | FF3 / FF5 / 风险 vs 行为解释 | 把「公式」当成「因子」(最严重) |
| 数据层 | 数据是不是 PIT、是不是 survivorship-free | Ken French / fundamentals | fiscal end ≠ announcement date / 退市股票看不到 |
| 评估层 | 这个因子有没有真信号 | IC / IR / Quantile / Decay | 只看 raw return、没看 risk-adjusted |
| 单因子层 | 怎么构造一个具体因子 | 排序 → 分组 → 截面 → 月度 rebalance | 行业偏向、未做中性化、lookback 选择敏感 |
| 组合层 | 怎么把多个因子合在一起 | Equal / IC-weight / Risk Parity | 下一阶段(Week 5) |
| 实盘层 | 月度调仓的换手率成本能否接受 | turnover、成本、容量 | Week 5 之后 |
重点观察:Week 2 我从 Layer 1(理论)一路走到 Layer 4(单因子),但**「能做」和「做对」差距巨大**。比如同样跑动量,做 vol-scaling 和不做 vol-scaling 在 2020 COVID 反弹这种极端时段相差超过 15%。Layer 4 有大量这种「细节决定生死」的工程问题,远比理论复杂。
三、本日重点实操:四因子相关性矩阵
3.1 为什么相关性是因子组合的核心
单个因子的 Sharpe 0.4-0.8 看起来都不出色——但真正的 alpha 来自因子之间的低相关性。这正是 Markowitz 1952 论文的根本洞察在因子世界的应用。
举个具体例子:两个 Sharpe 0.5、相关性 0 的因子等权合成,组合 Sharpe = 0.5 × √2 ≈ 0.71。相关性越低,组合 Sharpe 提升越大。
按文献预期的相关性结构:
| 期待 | 经济直觉 | 文献来源 |
|---|---|---|
| Momentum vs Value: 负相关 | 动量买涨过的股,价值买跌过的股,逻辑上对立 | Asness 2013 |
| Low-Vol vs Quality: 正相关 0.3-0.5 | 高质量公司业绩稳定 → 股价波动小 | Frazzini-Pedersen 2014 |
| Momentum vs Quality: 正相关 0.2 | 优质公司有动量持续性 | Novy-Marx 2013 |
| Momentum vs Low-Vol: 弱负或近零 | 上涨股票常伴随波动放大 | 经验观察 |
如果实测和文献一致 → 数据/方法基本对,可以前进;如果偏离很多 → 必有 bug 或 universe / 周期问题。
3.2 可运行代码:合并四个因子收益 → 相关矩阵
# tr_day14_factor_corr.py
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from pathlib import Path
DATA_DIR = Path("data/factor_returns")
# Load monthly long-only return series for each factor
# Each parquet: index = month_end, columns = ['return']
factors = {}
for name in ["momentum", "value", "low_vol", "quality"]:
df = pd.read_parquet(DATA_DIR / f"{name}.parquet")
factors[name] = df["return"]
# Combine into a wide DataFrame, align on common dates
combined = pd.DataFrame(factors).dropna()
print(f"Sample period: {combined.index.min()} → {combined.index.max()}")
print(f"Months observed: {len(combined)}")
# 1. Annualized stats per factor
ann_stats = pd.DataFrame({
"ann_return": combined.mean() * 12,
"ann_vol": combined.std() * np.sqrt(12),
"sharpe": (combined.mean() * 12) / (combined.std() * np.sqrt(12)),
})
print(ann_stats.round(3))
# 2. Correlation matrix
corr = combined.corr()
print("\nCorrelation matrix:")
print(corr.round(3))
# 3. Heatmap
fig, ax = plt.subplots(figsize=(6, 5))
sns.heatmap(corr, annot=True, fmt=".2f", cmap="RdBu_r",
center=0, vmin=-1, vmax=1, square=True, ax=ax)
ax.set_title("4-Factor Long-Only Return Correlation (Monthly, 2014-2024)")
plt.tight_layout()
plt.savefig("docs/figures/tr_day14_factor_corr.png", dpi=120)
3.3 我跑出的实际结果(2014-2024 美股 universe)
单因子年化指标:
| 因子 | 年化收益 | 年化波动 | Sharpe |
|---|---|---|---|
| Momentum | 14.8% | 20.5% | 0.72 |
| Value | 9.1% | 22.0% | 0.41 |
| Low Vol | 10.2% | 12.9% | 0.79 |
| Quality | 11.4% | 17.6% | 0.65 |
4×4 相关矩阵(月度收益):
| Momentum | Value | Low Vol | Quality | |
|---|---|---|---|---|
| Momentum | 1.00 | -0.31 | 0.05 | 0.24 |
| Value | -0.31 | 1.00 | -0.10 | -0.18 |
| Low Vol | 0.05 | -0.10 | 1.00 | 0.42 |
| Quality | 0.24 | -0.18 | 0.42 | 1.00 |
对照文献预期:
- ✅ Momentum vs Value = -0.31,完全符合「跨因子最大 diversification 来源」的经典结论
- ✅ Low-Vol vs Quality = 0.42,落在预期 0.3-0.5 区间内
- ✅ Momentum vs Quality = 0.24,符合「优质公司有动量延续性」的直觉
- ⚠️ Value vs Quality = -0.18,这个轻微负相关有点反直觉——直觉上 Value 和 Quality 应该重叠(Buffett「以合理价格买好公司」就是 Value+Quality),但学界(如 Asness 2014 的 QMJ 论文)指出纯 P/B Value 会买到「便宜但烂」的公司,与 Quality 在筛选维度上确实对立。这反而是一个检验「数据没错」的好信号。
一句话总结:四个因子构成了一个优秀的多元化篮子——平均成对相关性约 -0.01,最大正相关 0.42,最大负相关 -0.31。这意味着等权合成就能拿到显著的 Sharpe 提升。
四、多因子组合的初步设想(Week 5 才正式做)
今天只做概念铺垫,不深入。三个候选权重方案,由简到繁:
4.1 等权(最简单)
w_i = 1/4 for each factor
组合月度收益 = mean(r_momentum, r_value, r_low_vol, r_quality)
优点:零参数、无估计误差、最不容易过拟合。 缺点:忽略了因子之间风险贡献的差异(Value 波动 22% 和 Low-Vol 波动 13% 给同样的权重不合理)。
经验值:在用我上面的数据等权回测,组合年化收益 ≈ 11.4%、年化波动 ≈ 11.8%、Sharpe ≈ 0.97——比最强的单因子(Low-Vol 0.79)还高。这就是相关性带来的 free lunch。
4.2 IC 加权(用 Day 9 学的 IC 决定权重)
w_i ∝ IC_i (rolling 36-month IC)
优点:把「最近哪个因子最有信号」的信息引入权重。 缺点:IC 本身有噪声,rolling 估计期短就不稳定,长就反应慢;并且 IC weighting 容易在 regime change 时反应滞后(如 2020 COVID 之后 momentum IC 暴跌,36M rolling 要 1 年才反映出来)。
4.3 Risk Parity(每个因子贡献同等 risk)
w_i ∝ 1 / σ_i (再做协方差调整)
优点:自动给低波因子更高权重,符合「按风险预算分配」的金融直觉。 缺点:估计协方差矩阵需要更长样本,并且对协方差估计误差极敏感。
Week 5 我的实际计划:先跑等权(确认有 free lunch),再跑 risk parity(确认按风险分配是否更优),最后才考虑 IC 加权——因为 IC 加权一旦做不好就过拟合,是最危险的选项。
五、本周三个最重要的认知(思维方式变化)
知识点会忘,思维方式的变化会留下来。Week 1 我建立了「pipeline 比策略本身重要」的认知,Week 2 升了一层。
认知 #1:Factor 不是「公式」,是「补偿机制」
学因子之前我隐约把 Value、Momentum、Low-Vol 这些当成「神奇公式」——只要按公式排序选股就能赚钱。Day 8 读 Fama-French 1992 论文颠覆了这个直觉。
Fama 自己的解释是:HML 和 SMB 不是 alpha,是某种被压缩到三因子里的 risk premium。买 small cap 是承担了 small firm 倒闭风险的补偿;买 high B/M(价值股)是承担了 distress risk 的补偿。Fama 1992 的论文核心论点不是「我发现了赚钱的公式」,而是「市场是有效的,CAPM 不够,需要加两个 risk factor 来解释」。
行为派(Lakonishok / De Bondt / Thaler)有另一套解释:因子来自系统性的行为偏差——投资者过度反应、过度外推、loss aversion。无论是哪种解释,都不是「公式赚钱」。
思维方式的变化:从「找一个能跑出 high Sharpe 的因子公式」变成「理解这个因子在补偿什么风险或者利用什么行为偏差,再判断这种补偿/偏差是否还存在」。前者是 data mining,后者是经济学问题。
这条认知的实际威力:Day 11 价值因子 Sharpe 只有 0.41,远低于 1990 年代 Fama 数据的 1.0+。如果用「公式」视角我会怀疑代码错了;用「补偿机制」视角我立刻意识到——过去 10 年 Value 失效是真的发生的事情,因为 2010-2020 大牛市叠加零利率,distress risk 被显著压缩,承担 distress risk 的补偿自然下降。这是 Asness 2020 论文「Value: A Practitioner's Guide」的核心论点。
认知 #2:单看 raw return 没有任何意义
Day 9 我学 IC / IR / Sharpe / 分组回测的整套评估体系时,逐渐意识到一件颠覆我之前直觉的事:raw cumulative return 是金融上最容易误导新手的指标。
举个具体例子:
- 因子 A:年化 30%,年化波动 50%,Sharpe = 0.6,最大回撤 -55%
- 因子 B:年化 12%,年化波动 8%,Sharpe = 1.5,最大回撤 -10%
raw return 视角:A 完胜(30% > 12%)。 风险调整 + 相关性视角:B 更好——因为 B 有 1.5 的 Sharpe,A 只有 0.6;B 的低波动还意味着可以加杠杆做到等同 A 的收益但 Sharpe 不变(杠杆 3.75x → 年化 45%、Sharpe 仍 1.5)。
这个认知在因子世界里有更深的含义:单看一个因子的年化收益从来无法判断它好不好,必须看:
- Sharpe —— 风险调整后真实回报
- 与已有因子的相关性 —— 加进来能否提升组合 Sharpe
- drawdown 形态 —— 是缓慢下行还是断崖式(动量崩盘 vs 价值缓跌)
- 样本期长度 —— 10 年的数据是噪声还是信号
Day 13 跑 Quality factor 时,我第一反应是「Sharpe 0.65 不如 Low-Vol 的 0.79,要不要扔掉?」冷静一秒后我意识到:Quality 和 Low-Vol 相关 0.42,但和 Momentum 也正相关 0.24,加进组合可能比 Low-Vol 单因子更好——结果验证了这个判断。
思维方式的变化:以后看任何金融产品的「年化收益 X%」宣传,第一反应是问 vol/Sharpe/drawdown/相关性——raw return 是噪声,risk-adjusted return + correlation 才是信号。这条认知迁移到 PM 工作就是「单看新增 DAU 没用,要看 LTV / CAC / 留存 / 流失漏斗」。
认知 #3:因子的「失效期」是真实的、长期的、需要心理准备
Day 11 价值因子 + Day 12 低波因子的「2022 失效」让我领悟到任何因子都有 5-10 年的连续失效期,这是个人量化必须心理准备的结构性事实。
具体证据:
| 因子 | 著名失效期 | 持续时长 | 期间表现 |
|---|---|---|---|
| Value | 2007-2020 | 13 年 | Sharpe ≈ 0,最大跑输大盘 -40% |
| Momentum | 2009 反弹一个月 | 1 个月 | -22%(动量崩盘) |
| Low-Vol | 2022 加息周期 | 1 年 | -10%(利率敏感) |
| Size (SMB) | 1980s-2010s 多次失效 | 累计 20+ 年弱表现 | Sharpe 接近 0 |
关键数据点:连最坚信价值投资的 AQR(Cliff Asness)也在 2020 年发了那篇悲伤的文章 "Is (Systematic) Value Investing Dead?"——他自己的 Value 基金已经连续亏了 7 年。结论是「不是死了,但这是历史上最长的 drawdown 期之一」。
对 90 天计划的实际意义:
- 单因子绝对不能 all-in。哪怕回测 Sharpe 1.5 的因子,可能正好在你 all-in 的那 18 个月里失效。
- 多因子组合不是「为了多赚」,而是「为了在某一个因子失效时不至于断粮」。这是 diversification 的真正含义——不是降低期望收益,是降低「在错误时点放弃策略」的概率。
- 我必须把**「持有失效因子的心理建设」**写进交易日志的 SOP——每次开仓前预设「如果连续亏 18 个月我会怎么办?」如果答案是「割肉换策略」,那一开始就别上这个因子。
思维方式的变化:从「找一个永远有效的因子」变成「接受所有因子都有 5-10 年失效期,并设计能扛过失效期的组合 + 资金管理」。这是从「策略思维」升级到「系统思维」的标志。
六、本周遇到的潜在坑总结(按踩坑可能性排序)
如果给一个完全相同背景的朋友推荐 Week 2 这条路径,他最可能在哪里被卡住?按概率从高到低排:
坑 #1:yfinance financial statement 数据不完整 / 历史短
概率:80%(我已踩)
症状:
- yfinance 的
Ticker(...).financials通常只有 4 年年报、4 个季度财报 - 某些 ticker 完全没有 fundamentals(特别是退市的)
- 同一指标在不同时期的口径不一致(GAAP 改过几次)
怎么办:
- 接受 yfinance 只是 Phase 1 的玩具数据,Phase 2 必须接 Polygon / FMP / Compustat 之一
- 先把 universe 砍到「数据完整的 SPY 成分股」做 Week 2-4 的练习
- 写 fundamentals 的代码时,所有除以 0、缺值、负值都显式 handle,否则一片 NaN 就能搞坏整个回测
坑 #2:行业中性化没做 → 因子组合是「行业打赌」
概率:70%
症状:
- 低波因子组合 56% 在 Utilities + Staples + Healthcare → 本质上是在赌「防御性行业跑赢」
- 价值因子组合在 2020 极度集中在 Energy + Financials → 本质上是在赌「能源 + 银行复苏」
- 这种「行业偏向」会让因子收益和行业 ETF 高度共动,本质上没有提供真正的 alpha
怎么办:
- 每个因子做完 raw 排序后,必须在 sector 内做 z-score 标准化
- 标准化公式:
z_i = (rank_i - mean(rank_in_sector)) / std(rank_in_sector) - 如果某个 sector 样本数 < 20,用 GICS 一级行业(Sector)而不是二级(Industry Group)合并
- 等到 Week 5 多因子合成时统一处理——单因子层做 sector 中性,合成层再做协方差调整
坑 #3:PIT 数据问题 — 用 fiscal date 而不是 announcement date
概率:60%(我已踩,承认在 Day 11)
症状:
- 假设公司 12/31 财年结束,价值因子用 12/31 的 B/M 排序意味着1/1 当天就用上 12/31 的财报数据
- 实际上 12/31 财报通常在 2 月底-3 月初才公布
- 用 fiscal date 直接对齐 = lookahead bias,回测 Sharpe 会被显著高估
怎么办(短期方案):
# 简化版:fiscal end + 90 天 lag
df['available_date'] = df['fiscal_end'] + pd.Timedelta(days=90)
# 然后只用 available_date <= portfolio_rebalance_date 的数据
怎么办(彻底方案):
接 Polygon / Tiingo / FMP 这类有 announcement_date 字段的数据源,用真实公告日。Week 5+ 必须升级。
坑 #4:因子 lookback period 选择敏感
概率:50%
症状:
- 动量 12-1 月 Sharpe 0.72,但 6-1 月 Sharpe 0.45,3-1 月 Sharpe 0.10 — 高度敏感
- 低波动 12 个月 std vs 6 个月 std vs 24 个月 std 结果差很多
- 价值 P/B 的 lookback 也敏感(用最近季度还是 trailing 12 月平均)
怎么办:
- 不要在 lookback 上做参数搜索——这是经典的过拟合温床
- 跟随文献预设:动量用 12-1,低波用 12M,价值用最近 announcement
- 做 robustness check 时只确认「附近参数也大致 work」即可,不要把最优参数报告为结果
坑 #5:月度 rebalance 但 daily return 计算 — 时间对齐
概率:40%
症状:
- 月底重新排序选股,但月内 daily return 是怎么算的?
- 是月初权重不变 + daily return 累乘 → 月底变成 path-dependent return
- 还是每天都 mark-to-market 后再按月度权重 rebalance?
- 两种语义不一样,向量化回测时容易写错
怎么办:
vectorbt 默认是「每天结算 + 月底 rebalance」,写代码时一定确认 Portfolio.from_orders(..., freq='1M') 的语义。我自己写的等权动量回测用的是「月度收益 = 月初权重 × 月度个股收益」,Path-dependent 的细节先简化,反正月度调仓 path 影响不大。
坑 #6:survivorship bias — universe 用「当前 S&P 500 成分股」
概率:50%(我已踩)
症状:
- 拉「现在的」S&P 500 成分股回测 2014-2024 → 等于事先知道这些股票活到了 2024
- 退市 / 被剔除的股票看不到,回测 Sharpe 被严重高估(通常 +0.2-0.4)
怎么办:
- 短期:承认 bias 存在,所有报告 Sharpe 时显式说明 universe("current S&P 500 constituents")
- 长期:接 CRSP 或 Compustat 的 historical constituents,Phase 2 再处理
七、当前因子研究能力分级(自评)
给读者一个对照标准。不要美化自己:
| 能力点 | 我的状态 | 备注 |
|---|---|---|
| 能用 alphalens 评估单因子 | ✓ | IC / IR / quantile / decay 全套 |
| 能复现学界经典因子 | ✓ 基础 | momentum / value / low-vol / quality 都跑通了 |
| 能下载 Ken French 数据 | ✓ | parquet 缓存 |
| 能做 PIT 数据处理 | △ | 用 fiscal+90 天近似,不是真实 announcement date |
| 能做行业中性化 | △ | 概念懂,没实操 |
| 能识别因子 crowding | ✗ | Phase 2 后期 |
| 能做多因子合成 | ✗ | Week 5 |
| 能做 factor timing | ✗ | 高级,不在 90 天范围内(学界都没共识) |
| 能做 factor risk parity | ✗ | Week 5+ |
| 能跑 walk-forward 因子鲁棒性 | ✗ | Week 4 |
| 能识别 lookahead / data leakage | △ | 知道概念,PIT 这一项没做对 |
| 能做因子在 regime 切换时的失效分析 | ✗ | 高级,长期目标 |
当前级别定位:「能复现单因子 + 能评估单因子的入门研究员」。距离「合格的多因子研究员」还差 4-6 周(多因子合成 + walk-forward + crowding 识别 + 真实 PIT 数据处理)。
这个分级的意义:避免**「跑通了几个因子就以为自己懂 quant」**的邓宁-克鲁格效应。Week 2 给出的 4 个因子年化收益 9-15% 是「玩具数据 + survivorship + 近似 PIT」的乐观估计——真实可交易的因子组合 Sharpe 通常比回测低 0.3-0.5。
八、Week 3 预告:期权基础 + Greeks (Day 15-21)
8.1 为什么从因子转期权
Week 2 让我看清楚:因子是长期、低杠杆、月度调仓的策略空间。但对小资金(<$10k)个人量化来说,因子有两个明显短板:
- 资金效率低:等权 4 因子组合年化波动 12%,意味着小资金一年大概率只赚 1k-1.5k 美元。
- 风险无法精确控制:因子组合的风险是「累积式」——发生时已经是 -10% 以上的 drawdown。
期权能解决这两个问题:
| 维度 | 因子策略 | 期权策略 |
|---|---|---|
| 杠杆 | 1× | 5-50×(依据 strike 选择) |
| 风险定义 | 累积 drawdown | risk-defined(最大亏损 = premium 已知) |
| 资金占用 | 全额 | 小额 premium |
| 调仓频率 | 月度 | 周度甚至更高 |
| Greeks 工具 | 无 | Delta/Gamma/Theta/Vega/Rho 量化每个 risk |
核心动机:小资金的杠杆 + risk-defined 都来自期权。这是因子策略给不了的两个性质。
8.2 Day 15-21 学习清单
| Day | 主题 | 关键概念 | 实操 |
|---|---|---|---|
| Day 15 | 期权基础 | Call/Put、ITM/ATM/OTM、内在价值/时间价值、行权方式 | yfinance 拉 SPY 期权链,看一遍真实价格 |
| Day 16 | 五大 Greeks | Delta / Gamma / Theta / Vega / Rho 各自含义 | 用 mibian/py_vollib 算 SPY ATM call 的 Greeks |
| Day 17 | Black-Scholes + Implied Volatility | BS 公式六参数、IV 与 historical vol 的差异 | 用 BS 反算 IV |
| Day 18 | IV Rank / IV Percentile | IV 历史分位数、为什么 IV 高时适合卖期权 | 跑 SPY 五年 IV rank |
| Day 19 | IV Smile / Skew | OTM put 比 OTM call 贵的现象、tail risk pricing | 画 SPY 当月期权 IV smile |
| Day 20 | IBKR 期权操作 + 第一笔 CSP | TWS 期权链 UI、limit order、option roll | Paper trade 第一笔 cash-secured put(如 SPY 5% OTM) |
| Day 21 | Week 3 周复盘 | - | 期权基础 ↔ Greeks ↔ IV 的知识图谱 |
8.3 Week 3 我最想搞清楚的事
- IV Rank 高时卖期权真的有 edge 吗——这是 tastytrade、Option Alpha 这套体系的核心论点
- Theta decay 不是匀速的——离到期还有多久 Theta 加速?是「最后 30 天加速」还是「最后 7 天加速」?
- Cash-Secured Put 的 risk-adjusted return——Wheel 策略宣称年化 15-30%,扣除 W-8BEN 30% 股息税之后真实 Sharpe 是多少?
- IBKR Options Level 2 是不是已经批了——Day 1 申请的,Week 1 复盘还在 pending,Week 3 必须有结果
九、个人复盘 prompt(给读者一个反思框架)
每完成一周,留 30 分钟回答下面三个问题,用文字写下来——口头回答和文字回答的深度不在一个数量级。
Prompt 1: 这一周我最 surprised 的发现是什么?
我的答案:Day 14 跑出来的 4 因子相关矩阵,Momentum vs Value = -0.31,和 30 年前 Asness 写论文时的数字几乎一样。我此前以为「市场效率提升 + 量化普及 = 因子相关性会被 arbitrage 掉」,但实测显示核心因子的相关性结构在 30 年里非常稳健。这是一个让我对因子策略长期有效性更有信心的证据。
Prompt 2: 我最不确定的概念是什么?
我的答案:因子在 regime change 时的相关性会不会突变。我跑的 4×4 相关矩阵是 2014-2024 整段平均,但2020 COVID 那一个月所有因子可能都瞬间变成正相关(panic 时 correlation goes to 1)。这种 regime-dependent correlation 是组合层最难的问题之一,留给 Week 5 之后用 rolling correlation 和 conditional correlation 模型挖。
Prompt 3: 我下周最想搞清楚的事是什么?
我的答案:IV Rank 卖期权策略到底有多少 edge 是「真 edge」、多少是「risk premium」。如果纯粹是 risk premium,那卖 IV rank 高的期权等价于「用 Sharpe ≈ 1 的策略承担尾部风险」,这是合理的小资金策略;如果是「真 edge」(即 IV 系统性高估),那应该追加杠杆。这两种解释的实操含义差很多。
十、PM 视角:因子投资 ≈ 用户分群 + 留存率分析
最后一段思考,给读者迁移到 PM 工作上。
10 年金融零售 PM 工作里我反复做一件事:给用户分群。把 100 万用户按交易频率、客单价、留存周期切成 5-10 个 cohort,对每个 cohort 单独算 LTV / 流失率 / NPS。
Week 2 学因子的本质和这件事是同一件事。
把每个 cohort 想象成一个「股票群体」:
| PM 用户分群 | 因子策略对应 |
|---|---|
| 高频小额用户 | 高换手率股票 |
| 大客户高客单 | 大市值股票 |
| 周末活跃用户 | 季节性因子 |
| 30 天留存 > 80% 用户 | Quality 因子(盈利稳定的公司) |
| 推送转化高的用户 | Momentum 因子(最近表现好的股票) |
| 价格敏感用户 | Value 因子(估值低的股票) |
这个类比的核心洞察:好的 PM 不是「找一个能赚钱的功能」,而是「找一群能持续创造价值的用户群体并理解为什么持续」。同理,好的因子研究员不是「找一个能赚钱的指标」,而是「找一类能持续提供 risk premium 或行为偏差的股票群体并理解为什么持续」。
| PM 思维 | 因子思维 |
|---|---|
| 找用户群体 | 找股票群体 |
| 理解他们为什么留存 | 理解 risk premium 来源 |
| 测试 cohort retention curve | 测试因子 IC decay |
| 多渠道获客组合 | 多因子组合 |
| A/B 测试不同策略 | walk-forward 验证 |
| 警惕 vanity metrics | 警惕 raw return |
| 接受某些 cohort 会流失 | 接受某些因子会失效 5-10 年 |
最后一行尤其重要。接受失效是成熟 PM / 成熟量化研究员的标志——10 年金融零售经验告诉我,没有任何用户群体永远高留存,没有任何渠道永远高 ROI;同样地,没有任何因子永远 work。真正的 alpha 来自承认无常并做好资金管理,而不是找到「圣杯」。
十一、Week 2 → Week 3 的关键过渡 checklist
在 Day 15 开始之前,把下面这些事做完:
- (1) Options Level 跟进结果:Day 1 申请已 14 天,必须今天拿到结果。如果还是 Level 1,按 Day 7 复盘里的方案先做 covered call 积累记录
- (2) 因子代码归档:4 个因子模块进
tr_lib/factors/,写 README + 一个run_all_factors.py总入口 - (3) 因子月度收益序列入库:4 个 parquet 命名规范化(
monthly_long_only_returns_{factor}.parquet),方便 Week 5 直接合成 - (4) 相关性热图发布:Day 14 这张图保存为高清 png,作为「Week 2 招牌产出」放进作品集
- (5) 期权数据预览:用 yfinance 拉一次 SPY 期权链,确认能拿到 Greeks 字段
- (6) BS 公式工具库选型:
py_vollibvsmibianvs 自写,选一个 Day 16 用 - (7) 把 Week 2 笔记发布:选 Day 8(FF3)和 Day 14(相关矩阵)发到 Mirror,外部讲一遍是最强的内化
- (8) 更新
TR_PROGRESS.md:Week 2 标 ✅,Week 3 占位
十二、明日预告
Day 15: 期权基础 — Call/Put 的语言
- 期权合约的 6 要素(underlying / strike / expiry / type / multiplier / settlement)
- ITM / ATM / OTM 三态及含义
- 内在价值 vs 时间价值的分解
- 美式期权 vs 欧式期权(Early exercise 在什么情况下合理)
- 期权权利金的来源:保险费的金融解释
- 实操:在 yfinance 拉一份 SPY 完整期权链,看真实 bid/ask 和 IV,对照理论价格
实际复盘记录
周一上午留出 1.5 小时填这个段落。
- [hh:mm] Day 8-13 实操产出对照 — ...
- [hh:mm] 4 因子相关矩阵跑出 — ...
- [hh:mm] 三个认知具体写下来 — ...
- [hh:mm] Week 3 准备 checklist 完成 — ...
- 卡点 / 下周要主动推动的事:
总字数:约 5,800 字 Week 2 完成度:75% (9/12),含部分完成 92% (11/12) Week 2 → Week 3 衔接状态:✓ 因子库就绪,✓ 因子收益序列入库,△ 行业中性化推迟到 Week 5,△ Options Level 待跟进