feat: add comprehensive learning path for quantitative trading

This commit is contained in:
tigerenwork 2026-06-08 00:54:49 +08:00
parent 5f7537a01d
commit 7822e6d363
1 changed files with 607 additions and 0 deletions

607
doc_09_learning_path.md Normal file
View File

@ -0,0 +1,607 @@
# 量化交易学习路径:从程序员到独立研究者
> **目标读者**:有编程经验的开发者,量化知识和股票交易知识趋近于零。
> **前置条件**Python 熟练,了解 numpy/pandas 基本用法。
> **学习方式**:概念先行 → Demo 跟进 → 动手修改 → 平台实战。
> **预计时间**6-12 周(业余时间,每周 8-12 小时)。
---
## 目录
1. [你的起点:程序员学量化的优势和陷阱](#1-你的起点程序员学量化的优势和陷阱)
2. [路线图总览](#2-路线图总览)
3. [第一阶段:基础交易概念(第 1 周)](#3-第一阶段基础交易概念第-1-周)
4. [第二阶段:数据管道(第 2-3 周)](#4-第二阶段数据管道第-2-3-周)
5. [第三阶段:策略与回测(第 4-6 周)](#5-第三阶段策略与回测第-4-6-周)
6. [第四阶段:因子研究(第 7-8 周)](#6-第四阶段因子研究第-7-8-周)
7. [第五阶段:组合优化(第 9-10 周)](#7-第五阶段组合优化第-9-10-周)
8. [第六阶段:实战项目 — ETF 轮动(第 11-12 周)](#8-第六阶段实战项目--etf-轮动第-11-12-周)
9. [从 Demo 到平台的切换时机](#9-从-demo-到平台的切换时机)
10. [贯穿全程的学习方法](#10-贯穿全程的学习方法)
---
## 1. 你的起点:程序员学量化的优势和陷阱
### 你的优势
- **代码不是障碍**。Demo 的逻辑你看得懂,不需要花时间学 Python 语法。
- **系统思维**。事件驱动架构、数据管道、模块化设计——这些对你是天然的语言。
- **调试能力**。策略跑不出效果?你会 print 中间变量、画分布图、对比预期值,而不是对着屏幕发呆。
### 程序员学量化最常见的陷阱
| 陷阱 | 表现 | 为什么有害 |
|------|------|-----------|
| **把代码复杂度当成策略质量** | "我这个策略用了 LSTM + Transformer + 强化学习" | 复杂的模型 ≠ 能赚钱的策略。很多最赚钱的策略是小学算术级别的公式 |
| **过度关注实现,忽略概念** | 上来就写代码,不知道 Sharpe 和 Sortino 的区别 | 你写再多代码也是在错误的路上加速 |
| **把回测结果当真** | 回测年年化 50%,以为自己找到了圣杯 | 99% 是过拟合、前视偏差或幸存者偏差。回测不是验证策略好不好,是验证策略有没有明显漏洞 |
| **跳过模拟交易直接实盘** | 回测漂亮 → 真金白银 → 亏钱 | 回测和实盘之间有巨大的鸿沟:成交价格、滑点、流动性、交易心理……模拟交易是发现这些的唯一零成本方式 |
| **追求全自动,排斥理解** | 调库跑回测,只看最终 Sharpe 数字 | 你不知道策略什么时候会失效,因为你不知道它赚的什么钱 |
> **核心原则:先理解概念,再写代码。先小数据手动算,再全市场自动跑。先模拟交易,再实盘。**
---
## 2. 路线图总览
```
第一周 基础交易概念
"什么是股票、什么是ETF、怎么看K线"
第二~三周 数据管道 (Demo 1)
"原始数据长什么样、为什么要清洗、收益率怎么算"
第四~六周 策略与回测 (Demo 2 → Demo 3)
"怎么用均线/RSI生成买卖信号、怎么回测、怎么看绩效报告"
第七~八周 因子研究 (Demo 4)
"怎么判断一个指标有没有预测能力、IC是什么、因子怎么合成"
第九~十周 组合优化 (Demo 5)
"持有多只股票时怎么分配权重、有效前沿是什么意思"
第十一~十二周 实战项目 (Demo 7)
"把学到的全部串起来ETF轮动策略 + 真实数据 + 绩效分析"
之后 平台实战
"在聚宽/米筐上用全市场数据验证策略 → 模拟交易 → 实盘"
```
每个阶段的结构一致:
```
① 先阅读 doc_0X_xxx.md 的概念部分 (30 分钟)
② 打开 demo 对应的 .py 文件,读代码和注释 (1 小时)
③ 跑一遍 demo看输出图表 (30 分钟)
④ 动手修改一个参数 or 实现一个变体 (1-2 小时)
⑤ 回答 "我学到了什么" (10 分钟写笔记)
```
---
## 3. 第一阶段:基础交易概念(第 1 周)
### 3.1 需要理解的概念
如果你是程序员但没炒过股,这些是你必须补齐的基础知识。**不要跳过**——后面的所有 Demo 都建立在这些概念之上。
#### 股票基础
| 概念 | 一句话解释 | 为什么要知道 |
|------|-----------|-------------|
| **股票 (Stock)** | 上市公司的所有权份额。买 1 股 = 你拥有公司的一小部分 | 所有策略操作的对象 |
| **A 股** | 在中国大陆交易所(上交所/深交所)上市交易的股票 | 你的策略最终要在这个市场上跑 |
| **股票代码** | 每只股票的唯一标识,如 `000001.SZ`(平安银行)、`600519.SH`(贵州茅台) | 代码即数据索引 |
| **开盘价/收盘价** | 每个交易日第一笔/最后一笔成交的价格 | 收盘价是大部分策略使用的基准价 |
| **最高价/最低价** | 当天成交的最高/最低价格 | OHLC 中的 H 和 L |
| **成交量 (Volume)** | 当天成交了多少股 | 衡量市场活跃度和流动性 |
| **K 线 (Candlestick)** | 把 O/H/L/C 四个价格画成一根"蜡烛" | 技术分析的最基本可视化单元 |
| **T+1 制度** | A 股今天买的股票明天才能卖 | 日频策略必须知道的事——你今天发出的买入信号,买了以后今天不能卖 |
#### ETF 基础
| 概念 | 一句话解释 |
|------|-----------|
| **ETF (交易型开放式指数基金)** | 一种在交易所买卖的基金,追踪某个指数或行业。买 1 份芯片 ETF ≈ 同时买了芯片行业的一篮子股票 |
| **行业 ETF** | 追踪某个行业的 ETF如芯片 ETF (159995)、消费 ETF (159928) |
| **宽基 ETF** | 追踪大盘指数的 ETF如沪深 300 ETF (510300) |
| **为什么个人投资者适合 ETF** | 避免个股暴雷(财务造假、退市)、降低选股难度、流动性好、手续费低 |
#### 量化交易基础
| 概念 | 一句话解释 |
|------|-----------|
| **策略 (Strategy)** | 一套明确的规则,告诉你什么时候买、买多少、什么时候卖 |
| **回测 (Backtest)** | 在历史数据上模拟策略的表现,回答"如果过去按这个规则交易,结果会如何" |
| **收益率 (Return)** | 价格变化的百分比:`r = (今天价格 / 昨天价格) - 1` |
| **年化收益率 (CAGR)** | 把总收益率折算成"平均每年赚多少" |
| **波动率 (Volatility)** | 收益率的标准差,衡量"价格有多颠簸" |
| **夏普比率 (Sharpe Ratio)** | `(年化收益 - 无风险利率) / 年化波动率`,衡量"每承担一单位风险,能赚多少钱" |
| **最大回撤 (Max Drawdown)** | 从历史最高点到最低点的最大跌幅。如果策略历史上最多亏过 30%,你能承受吗? |
| **过拟合 (Overfitting)** | 策略在历史数据上表现极好,但在未来数据上表现极差——你只是记住了历史,没有找到规律 |
| **前视偏差 (Look-Ahead Bias)** | 回测中错误地使用了"未来的数据"做决策。例如用今天的收盘价决定今天的交易——但今天收盘时你还没法交易。代码层面最常犯的错误是 `bfill()` |
#### 学习资源
- 任何一本 A 股入门科普书的前两章(什么是股票、怎么开户、怎么看行情软件)
- [聚宽课堂](https://www.joinquant.com/help) 的"量化交易入门"系列(免费、中文、半小时看完基础概念)
- 打开东方财富或同花顺 App随便翻几只股票感受一下 K 线图、成交量柱、PE/PB 数字——建立直观感觉
### 3.2 不急着碰代码
这一周**不需要打开 Demo**。你需要的是建立金融直觉:当你听到"这只股票今天涨了 5%"你脑子里应该有个画面——K 线跳上去、成交量可能放大了、PE 可能变高了。这种东西 Demo 教不了你,只能靠多看行情软件培养。
---
## 4. 第二阶段:数据管道(第 2-3 周)
> **配套 Demo**: `quant_data_pipeline_demo.py` (920 行)
> **配套文档**: `doc_01_data_pipeline.md`
> **核心问题**: 原始行情数据长什么样 → 怎么把它变成能研究的数据
### 4.1 先理解的概念(读 doc_01 前先想清楚)
| 概念 | 为什么重要 |
|------|-----------|
| **复权 (Adjustment)** | 股票分红或拆股时价格会跳空。不复权的话,你的策略会看到虚假的"暴跌"信号 |
| **前复权 vs 后复权** | 前复权:历史价格按今天的股本折算(当前价格真实,历史价格被修改)。大部分策略用前复权 |
| **简单收益率 vs 对数收益率** | 对数收益时间可加(`ln(P_t/P_0) = Σ ln(P_i/P_{i-1})`),统计性质更好。日频差异极小,但月频以上必须区分 |
| **缺失值处理 (ffill)** | 停牌时用前一天的价格填充。**只有 ffill 是安全的**——bfill 会把未来价格泄露到今天 |
| **异常值 (Outlier)** | 一天涨 500% 多半是数据错误而不是真实行情。不处理的话你的均值和标准差全被拉偏 |
| **Winsorize (缩尾)** | 不删除异常值,而是把它"拉回"到合理边界。保留数据量,同时消除极端值影响 |
| **涨跌停 (Price Limit)** | A 股 ±10% 涨跌停ST 股 ±5%)。涨停日的 +10% 是真的价格,但你买不到——策略需要标记这些天 |
### 4.2 如何 Dig In
**第一步:跑一遍 Demo 11 小时)**
```bash
python quant_data_pipeline_demo.py
```
不要改任何代码。观察输出:
- 6 个 Topic 都生成了什么图表
- 每个 Topic 的 print 输出说了什么
- DataPipeline 类的 `run()` 方法执行了哪 5 个 Step
**第二步读代码画出数据流2 小时)**
```
原始价格 Panel (未复权)
↓ generate_raw_stock_data()
→ 复权 (forward_adjust / backward_adjust)
→ 简单收益 vs 对数收益对比
→ 多标的 Panel + 缺失值填充 (ffill only!)
→ 异常值检测 (MAD) + Winsorize
→ 涨跌停标记
→ 交易日历对齐
→ DataPipeline.run() 端到端
```
读完代码后,合上文件,自己画一遍这条数据流。如果能不看代码画出 6 个步骤,说明你理解了。
**第三步动手修改2 小时)**
搞三个微小的改动,跑通就能建立信心:
1. **改参数看影响**:把 `winsorize_pct=(0.01, 0.99)` 改成 `(0.05, 0.95)`,看收益率分布怎么变
2. **改检测阈值**:把 `detect_outliers_mad(series, threshold=5.0)` 的 threshold 改成 3.0 和 7.0,观察检测出的异常值数量变化
3. **自己造一个带问题的数据集**:手动改几天的价格为 NaN 或极端值,看 DataPipeline 清洗后的结果是否正确
**第四步概念验收20 分钟)**
能用自己的话回答以下问题,就过了:
- 为什么 bfill 在量化研究中是危险的?
- MAD 和 Z-score 哪个更稳健?为什么?
- 涨跌停日的数据应该删除还是保留?为什么?
---
## 5. 第三阶段:策略与回测(第 4-6 周)
> **配套 Demo**: `quant_strategy_backtest_demo.py` (912 行) + `quant_event_driven_backtest_demo.py` (1532 行)
> **配套文档**: `doc_02_strategy_backtest.md` + `doc_03_event_driven_backtest.md`
> **核心问题**: 怎么把"感觉要涨"变成可量化的规则 → 怎么在历史上验证这个规则
### 5.1 先理解的概念
#### 技术指标
| 指标 | 一句话 | 属于哪一类 |
|------|--------|-----------|
| **SMA (简单移动平均)** | 过去 N 天收盘价的平均值 | 趋势跟随 |
| **EMA (指数移动平均)** | 近期价格权重更高,比 SMA 反应更快 | 趋势跟随 |
| **RSI (相对强弱指数)** | 0-100 的值,>70 超买(该跌了),<30 超卖该涨了 | 均值回归 |
| **MACD** | 两条 EMA 的差值,反映趋势的强度和方向 | 趋势跟随 |
| **布林带 (Bollinger Bands)** | SMA ± 2×标准差。价格碰到下轨 = 超卖,碰到上轨 = 超买 | 均值回归 |
#### 策略概念
| 概念 | 为什么重要 |
|------|-----------|
| **趋势跟随 (Trend Following)** | 涨了就追、跌了就卖。在趋势市赚钱,在震荡市反复打脸 |
| **均值回归 (Mean Reversion)** | 涨多了就卖、跌多了就买。在震荡市赚钱,在强趋势市被趋势碾过 |
| **两类策略的互补性** | 没有任何策略能同时在趋势市和震荡市赚钱。你必须知道你的策略在什么市场环境中会失效 |
| **金叉 / 死叉** | 短期均线上穿长期均线 = 金叉(买)。下穿 = 死叉(卖) |
#### 回测概念
| 概念 | 为什么重要 |
|------|-----------|
| **向量化回测** | 用 pandas 数组运算一次性算出整个历史的所有收益。速度快,但无法模拟复杂交易逻辑 |
| **事件驱动回测** | 逐天模拟真实交易流程(行情→信号→订单→成交)。速度慢,但真实度高,和实盘系统架构一致 |
| **滑点 (Slippage)** | 你下单时的价格和实际成交价格的差异。大单、高波动时滑点更严重 |
| **佣金 (Commission)** | 券商手续费。A 股 ETF 佣金约万三0.03%),单向 |
| **印花税 (Stamp Duty)** | 政府收的交易税。A 股 ETF 仅卖方收 0.1% |
| **训练集 vs 测试集** | 在训练集上优化参数,在测试集上验证。如果在同一份数据上既优化又验证,你只是在过拟合 |
| **滚动前向验证 (Walk-Forward)** | 用历史数据训练 → 用未来数据测试 → 向前滚动。防止过拟合的标准做法 |
### 5.2 如何 Dig In — Demo 2向量化回测
**第一步:跑 Demo 21 小时)**
输出一张大图,包含 6 个子图:价格+均线信号、RSI、布林带、MACD、净值曲线、回撤曲线。
你关注的三个数字:**Sharpe**、**Max Drawdown**、**Win Rate**。这三个数字的组合比任何一个单独看都有意义。
**第二步逐函数阅读3 小时)**
```
generate_price_series() ← 几何布朗运动生成模拟价格
sma() / ema() / rsi() / macd() / bollinger_bands() ← 纯数学,你作为程序员应该 5 分钟看明白
MA Crossover 信号: short_ma > long_ma → +1 (做多)
RSI 信号: RSI < 30 超卖买入, RSI > 70 → 超买卖出
VectorizedBacktester 类:
_run(): 信号 × 日收益率 = 策略日收益, 扣除交易成本
metrics(): 返回全套绩效指标
Walk-Forward: 80% 训练 → 网格搜索最优参数 → 20% 测试验证
```
**第三步动手修改2 小时)**
1. **改均线参数**:把 SHORT_WIN=20, LONG_WIN=60 改成 (5,20), (10,30), (50,200),对比 Sharpe 的变化
2. **改 RSI 阈值**:把 OVERSOLD=30, OVERBOUGHT=70 改成 (20,80) 和 (40,60),观察交易频率和绩效变化
3. **自己实现一个新的指标策略**:基于布林带的策略——价格触及下轨买入、回到中轨卖出。不需要完美,重点是体验"信号规则 → 回测 → 看报告"的完整循环
**第四步:概念验收**
- 均线策略在什么时候疯狂亏钱?看图找答案(提示:价格横盘震荡时均线反复交叉)
- 为什么训练集的 Sharpe 总是高于测试集?
- `ma_signal.shift(1)` 里的 shift(1) 是干嘛的?删掉它会怎样?
### 5.3 如何 Dig In — Demo 3事件驱动回测
> **关键认知**Demo 3 不是为了"再学一种回测方法"。它是为了让你理解**实盘交易系统是什么架构**。你未来用 vnpy 或自己写实盘系统,架构就是 Demo 3 的样子。
**第一步:跑 Demo 3对比 Demo 230 分钟)**
同一个策略MA Crossover 20/60分别在 Demo 2向量化和 Demo 3事件驱动上跑。结果不一样——想想为什么不一样提示成交时机、最低佣金、整数股数
**第二步理解事件循环重点2 小时)**
这是整个 Demo 系列最重要的架构图。你必须能闭着眼睛画出来:
```
Event Queue (FIFO)
├── MarketEvent ← DataHandler 逐天发送行情
├── SignalEvent ← Strategy 收到行情后生成信号
├── OrderEvent ← Portfolio 决定下多少单
└── FillEvent ← SimulatedBroker 模拟成交
主循环:
while 还有更多数据:
1. DataHandler.stream_next() → 推一个 MarketEvent
2. Broker.fill_pending(bar) → 昨天订单今天开盘成交(无前视偏差!)
3. while 队列不空:
MarketEvent → Strategy.on_market()
SignalEvent → Portfolio.on_signal()
OrderEvent → Broker.on_order()
FillEvent → Portfolio.on_fill()
4. Portfolio.record_equity() → 记录当日净值
```
**第三步动手修改1 小时)**
不需要大改。做一个概念验证就行——在 `Portfolio.on_signal()` 里加一个"单只股票最大仓位 20%"的限制:
```python
# 在 on_signal 中,计算 qty 后插入
max_qty = int((self.cash * 0.20) / current_price)
qty = min(qty, max_qty)
```
看看这个简单的风控规则对回测结果有什么影响。
---
## 6. 第四阶段:因子研究(第 7-8 周)
> **配套 Demo**: `quant_alpha_factor_demo.py` (1023 行)
> **配套文档**: `doc_04_alpha_factor.md`
> **核心问题**: 在 5000 只股票中,怎么知道哪些指标"有用"、哪些是噪音?
### 6.1 先理解的概念
这是整个学习路径中概念密度最高的阶段。必须逐条吃透。
| 概念 | 一句话解释 |
|------|-----------|
| **Alpha 因子** | 一个从数据中提取信号、能预测股票未来收益的数学公式。例如"过去 12 个月涨得多的股票,未来还会涨"——这就是动量因子 |
| **IC (Information Coefficient)** | 因子的当期值 与 股票未来收益 之间的 Spearman 相关系数。IC 越高 = 因子预测能力越强 |
| **IC 均值** | IC 时间序列的平均值。>0.05 算有效,>0.08 算强 |
| **ICIR** | IC 均值 / IC 标准差。类似夏普比率——衡量预测能力的稳定性。>0.5 算不错 |
| **截面 (Cross-Section)** | 同一个时间点上横跨多只股票的比较。例如"今天 50 只股票里谁的动量最高" |
| **分层回测 (Quantile Backtest)** | 按因子值将股票等分为 5 组,看最高组是不是真的跑赢最低组。比 IC 更直观 |
| **去极值 (Winsorize)** | 截断异常值。Demo 1 学过 |
| **Z-score 标准化** | 使因子均值=0标准差=1。不同因子的量纲% vs 元 vs 倍数)才能互相比较 |
| **市值中性化** | 回归剔除市值的影响。否则你的"高动量因子"可能只是在选小市值股票——动量是假的,小市值效应才是真的 |
### 6.2 关键直觉
因子研究最核心的哲学问题:**这个因子赚的是什么钱?** 如果你答不上来,说明你还没理解。
- 动量因子赚的是"趋势持续性"的钱——人们反应不足,好消息需要时间消化
- 价值因子赚的是"市场过度悲观后恢复"的钱——坏消息被过度定价,回归均值时你赚了
- 低波动因子赚的是"机构不能买低波动股票"的钱——机构受基准约束被迫买高波动,低波动被低估
### 6.3 如何 Dig In
**第一步:跑 Demo 430 分钟)**
输出 `alpha_factor_demo.png`9 面板综合图)。重点关注:
- Panel 2: IC 时间序列 —— 哪个因子的 IC 最稳定?
- Panel 6: 分层回测 —— Q1 到 Q5 是不是单调递增?
- Panel 9: 因子衰减 —— IC 随着持有期延长怎么衰减?
**第二步概念串联2 小时)**
Demo 4 的流程 = 因子研究的标准工作流。把这个流程焊在脑子里:
```
§1 因子构建: 从原始价格中算出 5 个因子值
§2 预处理: 去极值 → Z-score → 市值中性化
§3 IC 分析: 每个因子和未来收益有多大相关性?
§4 分层回测: 因子真的能把好股票和坏股票分开吗?
§5 因子合成: 把多个因子合并成一个更强更稳的综合因子
§6 多空组合: 买因子分最高的 20%,卖最低的 20%
§7 因子衰减: 信号的有效期有多长?多久需要换仓?
```
**第三步动手修改2 小时)**
1. **改持有期**:把 `FORWARD_PERIOD = 21`1个月改成 5、42、63观察各因子的 IC 怎么变
2. **自己构造一个新因子**:比如"成交量变化率"——过去 5 日成交量均值 / 过去 20 日成交量均值 - 1。写进 FACTORS 字典,跑一遍 IC 分析
3. **去掉市值中性化**:注释掉 `neutralize_mktcap` 那一步,对比 IC 的变化。如果 IC 大幅提升——你的因子可能只是在选小市值股票
**第四步:概念验收**
- IC=0.03 的因子能用吗?为什么?
- 为什么 IC 在持有期 63 天时通常比 1 天时低?
- 市值中性化后 IC 下降了,说明什么?
---
## 7. 第五阶段:组合优化(第 9-10 周)
> **配套 Demo**: `quant_portfolio_optimization_demo.py` (950 行)
> **配套文档**: `doc_05_portfolio_optimization.md`
> **核心问题**: 选了 N 只好股票,每只各买多少?
### 7.1 先理解的概念
| 概念 | 一句话解释 |
|------|-----------|
| **有效前沿 (Efficient Frontier)** | 所有"最优组合"连成的线——在相同风险下收益最高,在相同收益下风险最低 |
| **马科维兹优化** | 输入:预期收益 μ + 协方差矩阵 Σ。输出:最优权重 w。问题是 μ 非常难估计 |
| **最小方差组合** | 有效前沿最左边的点——风险最低的组合。不需要估计任何收益,只需要协方差 |
| **最大夏普组合** | 从无风险利率出发,与有效前沿相切的那个点 |
| **风险平价 (Risk Parity)** | 每只资产对组合总风险的贡献相等。桥水全天候策略的理论基础。比等权分散得更彻底 |
| **Black-Litterman** | 贝叶斯框架:从市场均衡权重出发(先验),加入你自己的观点(后验)。解决了马科维兹"μ 难估计"的痛点 |
| **Ledoit-Wolf 收缩** | 协方差矩阵的估计是有误差的。收缩到结构化目标矩阵后的协方差更稳健——条件数更低 |
| **条件数 (Condition Number)** | 矩阵"病态"程度。条件数高 → 优化对输入误差极度敏感 → 鲁棒性差 |
### 7.2 关键直觉
组合优化不是让你"算出最优权重然后去赚大钱"。它的真正价值是**约束你的贪婪**——告诉你在分散风险的前提下,你能合理预期赚多少。
Demo 5 的图 1有效前沿图多看几眼那团灰色的随机组合云和那条金色的有效前沿曲线——任何一个随机组合要么在有效前沿下方同样风险但收益更低要么在有效前沿右侧同样收益但风险更高。这就是"分散投资"的数学本质。
### 7.3 如何 Dig In
**第一步:跑 Demo 530 分钟)**
输出 `portfolio_optimization_demo.png`。重点看:
- Panel 1: 有效前沿 + 5 个关键组合的位置
- Panel 4: 5 种策略的净值曲线——谁跑赢了谁?
- Panel 7: 月度收益箱形图——哪种策略的月度收益最平稳?
**第二步理解核心公式1 小时)**
打开 `portfolio_stats()` 函数:
```python
ret = w @ mu # 组合收益 = 权重 × 预期收益
var = w @ Σ @ w # 组合方差 = 权重 × 协方差矩阵 × 权重
vol = sqrt(var) # 组合波动率
sharpe = (ret - rf) / vol
```
这就是组合优化的全部数学。你作为程序员,线性代数不用教。
**第三步动手修改1 小时)**
1. **改约束**:把 `MAX_STOCK_WT = 0.15` 改成 `0.30`,看最大夏普组合的权重变化
2. **观察无约束组合**:把 `allow_short=True` 传给 `max_sharpe()`,看允许做空后权重长什么样(会有负权重)
3. **对比滚动回测**demo 里 §7 的滚动回测演示了 5 种策略在样本外的真实表现差异——最大夏普组合在样本外不一定是最好的
---
## 8. 第六阶段:实战项目 — ETF 轮动(第 11-12 周)
> **配套 Demo**: `quant_etf_rotation_demo.py` (849 行)
> **配套文档**: `doc_07_etf_rotation.md`
> **核心问题**: 把学到的全部串起来,做一个接近实战的策略
### 8.1 为什么以 ETF 轮动作为终章
- 逻辑简单:每月算一次动量 → 买最强的 3 只 ETF → 持有一个月 → 重复
- 实盘可行ETF 流动性好、T+0 可交易、不怕个股暴雷
- 整合了所有前置知识:数据清洗 (Demo 1) → 信号生成 (Demo 2) → 回测引擎 (Demo 3) → 因子/分层 (Demo 4)
- 双动量策略自带风控:熊市自动切换国债 ETF
### 8.2 如何 Dig In
**第一步:跑 Demo 7 + 读文档 + 读代码3 小时)**
这是你第一次看到"完整策略"的全貌。关注点不是代码细节,而是**各部分如何组合**。
**第二步切换到真实数据2 小时)**
```bash
python demo_akshare_data.py # 拉取真实 ETF 日线数据
```
然后把 `demo_akshare_data.py` 生成的 `data/etf_price_panel_clean.csv` 读入 Demo 7替代合成数据
- 找到 Demo 7 的合成数据生成部分(`returns_df` 和 `price_df`
- 替换为 `pd.read_csv("data/etf_price_panel_clean.csv", index_col=0, parse_dates=True)`
- 重新运行,对比合成数据的回测结果和真实数据的回测结果有什么不同
**第三步参数敏感性分析2 小时)**
对下面三个参数做简单扫描:
- `top_k` ∈ {2, 3, 4, 5}
- 动量回望期 ∈ {(3,1), (6,1), (12,1), (6,1)+(12,1)合成}
- 国债 ETF 切换阈值 ∈ {0, 国债收益率, 均线}
每个参数组合记录 Sharpe 和 Max Drawdown观察哪个参数最敏感。
**这个练习的价值不在于"找到最优参数"——而在于让你意识到:回测结果对这些参数有多敏感。如果你发现改一个参数 Sharpe 从 1.5 变成 0.3,说明策略非常脆弱。**
---
## 9. 从 Demo 到平台的切换时机
### 什么时候该从本地 Demo 切换到在线平台?
**当你开始问以下问题时:**
- "我想在沪深 300 成分股里按动量因子排序,选前 30 只——但本地只有 50 只股票的 Demo 数据"
- "我想知道这个因子在 2010-2020 年的表现——但本地没有这么长的全市场数据"
- "我想看看真实交易成本对策略的影响——但本地模拟的滑点模型太简单了"
**切换路径**
```
① 注册聚宽 或 米筐
② 在平台 Notebook 里重写你的因子/策略代码
(代码结构几乎一样,只是数据获取方式从 ak.fund_xxx() 变成平台内置 API)
③ 利用平台的现成数据,跑全市场回测
④ 开模拟交易,让策略自动运行
```
本地 Demo 是你的**概念实验室**,平台是你的**全市场验证场**。两者不是替代关系,是配合关系。
---
## 10. 贯穿全程的学习方法
### 十条原则
1. **先理解概念,再写代码。** 不知道 Sharpe 怎么算就写回测引擎,等于蒙着眼睛开车。
2. **小数据手动验证,再大规模自动跑。** 用 20 只股票验证你的逻辑正确,再放到 5000 只上跑。
3. **每次只改一个参数,看它的影响。** 一次改三个参数,你不知道是哪个导致了结果变化。
4. **把每次实验结果记录下来。** 日期、改了哪个参数、Sharpe/MaxDD 变成多少、你的判断。两周后你绝对记不清。
5. **读代码时,画出数据流图。** 合上文件能画出数据怎么流动,说明真懂了。
6. **不要迷信一个数字。** Sharpe 1.5 不代表策略好——可能只是过拟合。看一组指标Sharpe + MaxDD + Win Rate + Calmar。
7. **遇到不懂的,先手动算一遍。** "IC 到底怎么算的?"——取 5 只股票某一天的因子值和它们下一个月的收益,用 Excel 或 NumPy 手动算一遍 Spearman 秩相关。比看十遍文档都管用。
8. **对比永远比绝对值重要。** "我写的因子 IC = 0.04"——在 0.04 是好是坏?你得和经典因子(动量/反转/低波)的 IC 对比才知道。
9. **模拟交易是实盘的必修课。** 没有在模拟环境跑满 1-2 个月的策略,不上实盘资金。不是技术问题——是你会发现自己对策略的信任程度完全不够。
10. **如果一个策略你不能用三句话讲清楚它赚的是谁的钱,就不要投钱。**
### 每周时间分配
```
读文档 + 学概念: 1-2 小时
读代码: 1-2 小时
跑 Demo + 观察: 30 分钟
动手修改代码: 1-2 小时
写笔记: 20 分钟
浏览行情软件: 随意,建立市场感觉
─────────────────────────
每周总计: 5-8 小时
```
### 笔记模板
每个 Demo 学完后,用这个模板写 5 分钟笔记:
```
【Demo X: 名称】 日期:
三个核心概念:
1. ...
2. ...
3. ...
一个疑问 (还没想明白的事):
...
一个改动 (我改了什么、结果怎么变了):
...
```
---
## 附录:关键概念速查卡
```
┌──────────────┬─────────────────────────────────────────────┐
│ 数据层 │ │
├──────────────┼─────────────────────────────────────────────┤
│ 前复权 │ 历史价格按今天股本折算,当前价 = 真实价 │
│ ffill │ 向前填充缺失值;禁止 bfill (前视偏差) │
│ Winsorize │ 截断极端值到分位数边界,不删除数据点 │
│ MAD │ 比 Z-score 更稳健的异常值检测方法 │
├──────────────┼─────────────────────────────────────────────┤
│ 策略层 │ │
├──────────────┼─────────────────────────────────────────────┤
│ 趋势跟随 │ 追涨杀跌;震荡市反复亏损 │
│ 均值回归 │ 反转交易;强趋势中逆势被碾压 │
│ 金叉/死叉 │ 短期均线上穿/下穿长期均线 │
│ RSI │ 0-100>70 超买(该跌)<30 超卖(该涨)
├──────────────┼─────────────────────────────────────────────┤
│ 因子层 │ │
├──────────────┼─────────────────────────────────────────────┤
│ IC │ 因子值与未来收益的秩相关系数;衡量预测力 │
│ ICIR │ IC均值/IC标准差衡量预测稳定性 │
│ 截面标准化 │ 同一天内不同股票之间做 Z-score │
│ 市值中性化 │ 回归剔除市值影响,提取纯净的因子信号 │
│ 分层回测 │ 按因子分 5 组Q5-Q1 价差 = 因子收益 │
├──────────────┼─────────────────────────────────────────────┤
│ 组合层 │ │
├──────────────┼─────────────────────────────────────────────┤
│ 有效前沿 │ 风险收益空间中所有最优组合连成的曲线 │
│ 风险平价 │ 每只资产贡献相同风险;比等权更均衡 │
│ Black-Litterman│ 先验(市场均衡) + 你的观点 → 后验权重 │
├──────────────┼─────────────────────────────────────────────┤
│ 评估层 │ │
├──────────────┼─────────────────────────────────────────────┤
│ Sharpe │ (年化收益-无风险利率)/年化波动;>1 算不错 │
│ Max Drawdown │ 历史最大回撤;你能承受的极限是策略的底线 │
│ Calmar │ 年化收益/|最大回撤|;越高越好 │
│ 前视偏差 │ 回测中使用了未来信息 → 结果不可信 │
│ 幸存者偏差 │ 只回测现在还活着的股票 → 遗漏了退市的失败者 │
└──────────────┴─────────────────────────────────────────────┘
```