# SEC 原始 B/M 因子研究项目企划

> 面向 Quantitative Research 实习的研究型项目。本文档同时包含完整项目企划，以及第一个 notebook `00_setup_and_data_audit.ipynb` 的建设教程。项目目录已在 `/home/ubuntu/projects/factor-pricing-research/` 建立；代码文件当前只创建结构，不包含实现内容。

## 1. 项目定位

### 项目目标

从 SEC EDGAR/XBRL 原始申报数据构造 point-in-time Book-to-Market（B/M）因子，并与 Qlib 市场数据和 Kenneth French 学术 benchmark 对照，检验价值因子在严格样本筛选、行业控制、交易成本和样本外条件下是否仍然具有稳定的横截面解释力。

这不是“下载数据后跑一条回测曲线”的项目。主要展示能力是：

- 将经济含义转化为可证伪假设。
- 识别财务数据的公告时点，而不是只看会计期间。
- 从原始 XBRL facts 处理字段异构、修订、CIK/ticker 映射和缺失。
- 把因子定义、组合形成、收益标签和成本模型连成可审计的研究管线。
- 用统计推断区分统计显著、经济显著和数据挖掘结果。
- 对失败、覆盖不足和 survivorship bias 做清晰披露。

### 核心研究问题

> Does an SEC-native, point-in-time Book-to-Market factor produce a robust cross-sectional value premium after strict universe filters, industry controls, transaction costs, and walk-forward out-of-sample testing?

中文：在严格股票池、行业控制、交易成本和 walk-forward 样本外检验后，基于 SEC 原始 point-in-time 数据构造的 B/M 是否仍产生稳健的横截面价值溢价？

### 研究假设

- **H1：横截面预测。** 在组合形成时点 B/M 较高的股票，未来持有期平均收益更高。
- **H2：梯度。** 按 B/M 五分位形成的组合收益应呈现可解释的高低梯度，而不是只有单个极端组驱动。
- **H3：非单一暴露。** High-B/M 组合的结果不能完全由行业、规模或市场 beta 暴露解释。
- **H4：现实摩擦。** 加入换手、spread、slippage 后收益会下降；若净收益完全消失，应诚实报告因子不具备当前成本下的可交易性。
- **H5：时间稳定性。** 结果不应只由单一危机阶段或样本末期驱动；walk-forward OOS 的衰减幅度本身是研究结果。

## 2. 固定研究口径

| 维度 | 第一版决定 |
|---|---|
| 市场 | 美国交易所上市普通股全市场 |
| 样本期 | 2010 年起，以 SEC 覆盖审计结果确定可用起点 |
| 排除 | ADR、REIT、ETF、封闭式基金、优先股、权证、单位、金融业 |
| 小盘处理 | 形成期执行最低价格、市值和流动性过滤；保留过滤前后样本统计 |
| Book Equity | `Common Equity + Preferred Stock - Non-controlling Interest`；按字段优先级回退 |
| Market Equity | 每年 6 月底市值，来自 Qlib/市场数据层 |
| 信息时点 | 只使用 6 月形成日前已经提交并可获得的 SEC 财务信息 |
| B/M | `Book Equity / Market Equity`；负 Book Equity 主样本排除，单独做稳健性 |
| 排序 | NYSE breakpoints，五分位：Low、Q2、Q3、Q4、High |
| 主权重 | 市值加权 |
| 稳健性权重 | 等权 |
| 持有期 | 当年 7 月至次年 6 月，年度再平衡 |
| Benchmark | Kenneth French B/M 相关组合/因子、市场组合、等权市场组合 |
| 因子报告 | 五组收益梯度、High-Low、CAPM/FF alpha、风险和成本后表现 |

## 3. 数据架构

### 三层数据

1. **Layer 1：Qlib/市场数据**
   - 交易日期、复权价格或收益、成交量、市值、行业分类、股票状态。
   - 作用是提供 Market Equity、收益标签、交易成本代理和横截面标识。
   - Qlib 是工具和基线，不是本项目研究贡献。

2. **Layer 2：学术 benchmark**
   - Kenneth French Data Library 的因子和组合数据。
   - 作用是核对长期方向、定义差异和样本期差异。
   - 不把 French 数据直接冒充 SEC 原始因子。

3. **Layer 3：SEC point-in-time fundamentals**
   - `companyfacts`、公司提交记录、CIK/ticker 映射和 filing metadata。
   - 作用是从原始申报构造 Book Equity，并保留 filed date、form、fy、fp、frame、accn 等审计字段。

### SEC 数据流

```text
company universe
  -> CIK / ticker mapping
  -> SEC submissions and companyfacts
  -> select relevant XBRL facts
  -> normalize units and periods
  -> choose filed date / announcement availability
  -> construct Book Equity with fallback rules
  -> lag and point-in-time join to June market equity
  -> compute B/M
  -> NYSE quintile portfolios
  -> returns, exposures, inference, costs, OOS
```

### SEC 字段优先级与回退

字段实际名称会因公司和报表而变化，因此不假设单一 tag 覆盖全市场。每一条财务观测必须保留 `source_tag`、`source_form`、`filed`、`accn`、`fy`、`fp`、`unit` 和 `selection_reason`。

建议的逻辑优先级：

1. Common equity：优先使用可识别的 `CommonStockholdersEquity` 或同义公司扩展 tag。
2. Preferred stock：优先使用 `PreferredStockValue`、`PreferredStocksIncludingAdditionalPaidInCapital` 或同义 tag；若不存在则记为 0，并标记 `preferred_assumption`。
3. Non-controlling interest：使用 `MinorityInterest`、`NoncontrollingInterestInConsolidatedEntity` 等可识别 tag；缺失则记为 0，并标记假设。
4. 若 common equity 无法取得，回退到 `StockholdersEquity`，并将 `equity_fallback=True`。
5. 同一报告期多条事实时，选择在形成日前已 filed 的最新有效 observation；不读取形成日之后的修订版本。
6. 只保留与资产负债表时点匹配的季度/年度值，不把累计损益表期间直接当作权益余额。
7. 单位统一到美元；负 Book Equity 不截断，不在主样本中排序，另存负值诊断结果。

### CIK/ticker 与历史标识

- CIK 是 SEC 主键，ticker 只是市场数据连接字段。
- 保存映射有效日期、来源和一对多/多对一变化。
- 同一 ticker 的更名、合并、拆分和退市不能静默合并。
- 若无法安全匹配，宁可剔除并记录原因，不用模糊字符串匹配制造假连接。

## 4. 研究方法

### 4.1 形成与持有

每年 6 月最后一个交易日形成组合。对每只股票查询该日之前已经 filed 且符合财务期间要求的最新 Book Equity；用 6 月底 Market Equity 计算 B/M。组合从 7 月第一个交易日开始持有至次年 6 月末。

主结果采用市值加权，等权作为稳健性。排序切点使用 NYSE eligible universe 的 B/M 分位点，避免小盘股大量影响 breakpoints。报告每个组合的股票数、总市值、行业构成和小盘暴露。

### 4.2 组合与因子结果

- 五组：`Q1 Low`、`Q2`、`Q3`、`Q4`、`Q5 High`。
- 组合收益：等权和市值加权两套。
- 价值 spread：`High B/M - Low B/M`。
- 统计：均值、年化收益、波动率、Sharpe、最大回撤、Newey-West t-stat。
- 资产定价：CAPM alpha、Fama-French alpha；若使用额外因子必须明确来源和滞后。
- 稳健性：排除金融业为主结果；加入金融业、保留负 Book Equity、放宽微型股过滤作为单独版本。

### 4.3 暴露与中性化

第一版优先使用可解释的方法：

- 行业内排序后再按行业合并多空收益。
- 报告 High/Low 组合的市值、行业、beta 和流动性差异。
- 以市场 beta 和规模作为回归控制，报告控制前后 alpha 变化。
- 不把“回归后 alpha”描述为因果效应；只称为条件相关或残差解释。

### 4.4 成本与容量

```text
net_return = gross_return - commission - spread - slippage
```

至少三档成本：低、基准、高。换手按实际目标权重变化计算。扩展版本使用：

```text
market_impact ~ volatility * sqrt(order_value / ADV)
```

报告 break-even cost、不同资本规模下的净收益、ADV participation 和最大可承载资金。所有成本都是模型假设，不宣称等同真实执行成本。

### 4.5 Walk-forward OOS

禁止随机切分。B/M 的排序规则本身可以不训练，但仍使用时间顺序评估，避免根据全样本结果事后改变筛选规则。默认 expanding windows：

```text
Research / calibration: 2010-2015 -> test: 2016-2017
Research / calibration: 2010-2017 -> test: 2018-2019
Research / calibration: 2010-2019 -> test: 2020-2021
Research / calibration: 2010-2021 -> test: 2022-2023
Final untouched test: 2024-至今（以可用数据为准）
```

固定规则在 OOS 前写入配置。所有日期、过滤规则和字段回退结果均需可重建。

## 5. Notebook 计划

### 完整 notebook 结构

```text
notebooks/
├── 00_setup_and_data_audit.ipynb
├── 01_momentum_lab.ipynb
├── 02_value_lab.ipynb
├── 03_size_lab.ipynb
├── 04_volatility_risk_lab.ipynb
├── 05_liquidity_lab.ipynb
├── 06_quality_profitability_lab.ipynb
├── 07_technical_lab.ipynb
├── 08_cross_factor_comparison.ipynb
├── 09_new_factor_hypothesis.ipynb
├── 10_sec_data_audit.ipynb
├── 11_sec_book_equity_construction.ipynb
├── 12_bm_formal_test.ipynb
└── 13_final_robustness_and_oos.ipynb
```

项目按三阶段推进：`00-07` 先做经典因子 survey，`08-09` 比较因子并提出新假设，`10-13` 再做 SEC 原始数据和 B/M 正式验证。每类一个 notebook，不为每个因子单独建 notebook。

### Notebook 00：最小市场数据审计

`00_setup_and_data_audit.ipynb` 只负责认识 Qlib/市场数据，不负责 SEC 或 B/M。目标是用 15-25 个 cell 在半天到一天跑通：

- 检查环境、数据来源、schema、日期范围、股票数和字段定义。
- 检查 instrument/date 重复键、排序、价格、收益、市值和缺失。
- 构造严格来自下一期的 `fwd_return_1m`，并用 toy data 验证方向。
- 输出市场数据审计表，把交接文件保存给 Notebook 01。

`00` 明确不做：SEC API、Company Facts、CIK/ticker、XBRL tag、Book Equity、B/M、正式回测、复杂成本和 OOS。

### Notebook 01：第一个经典因子复现

`01_momentum_lab.ipynb` 只设一个主因子 `MOM_12_1`：过去 12 个月累计收益，跳过最近 1 个月。完成后再做有限敏感性 `MOM_3_1`、`MOM_6_1`、`REV_1M`。

教程对应两个 Notebook 的实际运行顺序：00 做 9 个最小 cell（契约、路径、来源、读取、重复键、字段逻辑、forward label、toy test、审计输出）；01 做 9 个核心 cell（契约、读取交接、公式、toy test、IC、分位数、权重、梯度、结论）。

### 后续阶段交付

- `08_cross_factor_comparison.ipynb`：因子相关性、收益相关性、规模/行业/beta 暴露和边际贡献。
- `09_new_factor_hypothesis.ipynb`：从 survey 异常出发，写经济动机、公式、baseline、ablation 和失败标准。
- `10_sec_data_audit.ipynb`：SEC API、Company Facts、CIK/ticker、字段覆盖和 filed date，只做数据审计。
- `11_sec_book_equity_construction.ipynb`：Common Equity + Preferred Stock - NCI、XBRL tag 回退、单位、修订和负权益。
- `12_bm_formal_test.ipynb`：6 月形成、7 月至次年 6 月持有、NYSE 五分位、French benchmark。
- `13_final_robustness_and_oos.ipynb`：行业/规模/beta 控制、成本、容量、Newey-West 和 walk-forward。

### Notebook 00 的最小 cell 顺序

1. Markdown：研究契约和问题边界。
2. Code：导入包、检查工作目录、创建输出目录。
3. Markdown：记录市场数据来源、价格/收益/市值定义和 survivorship 限制。
4. Code：读取 Qlib/市场快照并检查 schema、日期范围和股票数。
5. Code：检查 instrument/date 重复键、排序、价格、收益、市值和缺失。
6. Code：构造下一月 `fwd_return_1m`。
7. Code：用 toy data 验证 `shift(-1)` 方向。
8. Code：输出 `market_data_audit.csv` 和 `market_monthly_with_forward_return.parquet`。

### Notebook 01 的最小 cell 顺序

1. Markdown：固定 `MOM_12_1` 主因子和下一期标签。
2. Code：读取 Notebook 00 的交接文件。
3. Code：手动实现 `MOM_12_1`。
4. Code：用人工序列验证 `shift(1)` 和 rolling window。
5. Code：计算 Pearson IC、Rank IC 和 ICIR。
6. Code：用简单五分位做 baseline，随后再换成 NYSE breakpoints。
7. Code：计算等权/市值加权组合和 Q5-Q1。
8. Code：输出收益梯度、股票数和组合图。
9. Markdown：写 evidence、limits、failure analysis 和下一步。

## 6. 后续 survey notebook 统一模板

每类 notebook 采用以下顺序：经典定义 → Qlib 对应特征 → 原始字段 → 论文版本手动实现 → Qlib 版本对照 → 时间/lookahead 检查 → 分布和缺失率 → IC/Rank IC → 分位数组合 → 暴露分析 → 文献对照 → 风险和研究问题。

固定代表因子：

- Momentum/Reversal：`MOM_3_1`、`MOM_6_1`、`MOM_12_1`、`REV_1M`。
- Value：B/M、E/P、FCF/P。
- Size：Log Market Cap、Industry-relative Size、Small-minus-Big。
- Volatility/Risk：Historical Volatility、Downside Volatility、Market Beta、Maximum Drawdown。
- Liquidity：Dollar Volume、Turnover、Amihud Illiquidity、Volume Volatility。
- Quality/Profitability：ROE、Gross Profitability、Earnings Stability、Accruals。
- Technical/Price-Volume：RSI、ROC、Moving Average Distance、Price-Volume Correlation。

## 7. 交付物和验收标准

### 代码与数据

- 可安装环境文件和固定版本。
- 数据下载/读取脚本、配置文件和数据字典。
- 原始数据快照或明确的重新下载命令。
- SEC 字段回退、CIK/ticker 映射、样本剔除和 lookahead 日志。

### 研究报告

- 研究问题、经济机制、数据和定义。
- 五分位组合收益、High-Low、alpha、风险和成本后结果。
- 行业、规模、beta 暴露与中性化结果。
- OOS、子样本、负权益、金融业和微型股稳健性。
- 失败分析、数据限制、许可和不可复现部分。

### 最低完成标准

1. 一条命令可以重建主要输入表和图。
2. 因子形成只使用形成日前可获得信息。
3. 每个 B/M observation 可以追溯到 SEC tag、filed date、accn 和选择理由。
4. 有五组收益梯度、High-Low、Newey-West t-stat 和成本敏感性。
5. 主结果和稳健性结果分开，不能只报告最好的规格。
6. 报告明确说明 survivorship、数据覆盖和 SEC 修订限制。

## 8. 时间安排

按每天 2-3 小时估计 4-6 周；不把时间表写成机械日历，而按里程碑验收：

- **M0：** 研究契约、配置和目录结构冻结。
- **M1：** `00_setup_and_data_audit.ipynb` 跑通并输出覆盖率/时间审计。
- **M2：** SEC B/M 与 Qlib 市值成功连接，形成五分位预览。
- **M3：** 五组收益、High-Low、等权/市值加权和 benchmark 对照完成。
- **M4：** 行业/规模/beta 暴露、成本和 OOS 完成。
- **M5：** 报告、失败分析、一键复现和最终审计完成。

## 9. 官方资源

- SEC EDGAR：<https://www.sec.gov/edgar/search/>
- SEC Company Facts API 文档入口：<https://www.sec.gov/edgar/sec-api-documentation>
- Kenneth French Data Library：<https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html>
- Microsoft Qlib：<https://github.com/microsoft/qlib>
- yfinance：<https://github.com/ranaroussi/yfinance>
- FRED：<https://fred.stlouisfed.org/>

这些仓库和数据源是基线或工具，不等于本项目的原创贡献。项目原创性来自 SEC 原始数据构造、时间点审计、定义对照、组合检验和诚实的稳健性分析。
