33 KiB
量化交易学习路径:从程序员到独立研究者
目标读者:有编程经验的开发者,量化知识和股票交易知识趋近于零。
前置条件:Python 熟练,了解 numpy/pandas 基本用法。
学习方式:概念先行 → Demo 跟进 → 动手修改 → 平台实战。
预计时间:6-12 周(业余时间,每周 8-12 小时)。
目录
- 你的起点:程序员学量化的优势和陷阱
- 路线图总览
- 第一阶段:基础交易概念(第 1 周)
- 第二阶段:数据管道(第 2-3 周)
- 第三阶段:策略与回测(第 4-6 周)
- 第四阶段:因子研究(第 7-8 周)
- 第五阶段:组合优化(第 9-10 周)
- 第六阶段:实战项目 — ETF 轮动(第 11-12 周)
- 从 Demo 到平台的切换时机
- 贯穿全程的学习方法
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 股入门科普书的前两章(什么是股票、怎么开户、怎么看行情软件)
- 聚宽课堂 的"量化交易入门"系列(免费、中文、半小时看完基础概念)
- 打开东方财富或同花顺 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 1(1 小时)
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 小时)
搞三个微小的改动,跑通就能建立信心:
- 改参数看影响:把
winsorize_pct=(0.01, 0.99)改成(0.05, 0.95),看收益率分布怎么变 - 改检测阈值:把
detect_outliers_mad(series, threshold=5.0)的 threshold 改成 3.0 和 7.0,观察检测出的异常值数量变化 - 自己造一个带问题的数据集:手动改几天的价格为 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 2(1 小时)
输出一张大图,包含 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 小时)
- 改均线参数:把 SHORT_WIN=20, LONG_WIN=60 改成 (5,20), (10,30), (50,200),对比 Sharpe 的变化
- 改 RSI 阈值:把 OVERSOLD=30, OVERBOUGHT=70 改成 (20,80) 和 (40,60),观察交易频率和绩效变化
- 自己实现一个新的指标策略:基于布林带的策略——价格触及下轨买入、回到中轨卖出。不需要完美,重点是体验"信号规则 → 回测 → 看报告"的完整循环
第四步:概念验收
- 均线策略在什么时候疯狂亏钱?看图找答案(提示:价格横盘震荡时均线反复交叉)
- 为什么训练集的 Sharpe 总是高于测试集?
ma_signal.shift(1)里的 shift(1) 是干嘛的?删掉它会怎样?
5.3 如何 Dig In — Demo 3(事件驱动回测)
关键认知:Demo 3 不是为了"再学一种回测方法"。它是为了让你理解实盘交易系统是什么架构。你未来用 vnpy 或自己写实盘系统,架构就是 Demo 3 的样子。
第一步:跑 Demo 3,对比 Demo 2(30 分钟)
同一个策略(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%"的限制:
# 在 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 4(30 分钟)
输出 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 小时)
- 改持有期:把
FORWARD_PERIOD = 21(1个月)改成 5、42、63,观察各因子的 IC 怎么变 - 自己构造一个新因子:比如"成交量变化率"——过去 5 日成交量均值 / 过去 20 日成交量均值 - 1。写进 FACTORS 字典,跑一遍 IC 分析
- 去掉市值中性化:注释掉
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 5(30 分钟)
输出 portfolio_optimization_demo.png。重点看:
- Panel 1: 有效前沿 + 5 个关键组合的位置
- Panel 4: 5 种策略的净值曲线——谁跑赢了谁?
- Panel 7: 月度收益箱形图——哪种策略的月度收益最平稳?
第二步:理解核心公式(1 小时)
打开 portfolio_stats() 函数:
ret = w @ mu # 组合收益 = 权重 × 预期收益
var = w @ Σ @ w # 组合方差 = 权重 × 协方差矩阵 × 权重
vol = sqrt(var) # 组合波动率
sharpe = (ret - rf) / vol
这就是组合优化的全部数学。你作为程序员,线性代数不用教。
第三步:动手修改(1 小时)
- 改约束:把
MAX_STOCK_WT = 0.15改成0.30,看最大夏普组合的权重变化 - 观察无约束组合:把
allow_short=True传给max_sharpe(),看允许做空后权重长什么样(会有负权重) - 对比滚动回测: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 小时)
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. 贯穿全程的学习方法
十条原则
-
先理解概念,再写代码。 不知道 Sharpe 怎么算就写回测引擎,等于蒙着眼睛开车。
-
小数据手动验证,再大规模自动跑。 用 20 只股票验证你的逻辑正确,再放到 5000 只上跑。
-
每次只改一个参数,看它的影响。 一次改三个参数,你不知道是哪个导致了结果变化。
-
把每次实验结果记录下来。 日期、改了哪个参数、Sharpe/MaxDD 变成多少、你的判断。两周后你绝对记不清。
-
读代码时,画出数据流图。 合上文件能画出数据怎么流动,说明真懂了。
-
不要迷信一个数字。 Sharpe 1.5 不代表策略好——可能只是过拟合。看一组指标:Sharpe + MaxDD + Win Rate + Calmar。
-
遇到不懂的,先手动算一遍。 "IC 到底怎么算的?"——取 5 只股票某一天的因子值和它们下一个月的收益,用 Excel 或 NumPy 手动算一遍 Spearman 秩相关。比看十遍文档都管用。
-
对比永远比绝对值重要。 "我写的因子 IC = 0.04"——在 0.04 是好是坏?你得和经典因子(动量/反转/低波)的 IC 对比才知道。
-
模拟交易是实盘的必修课。 没有在模拟环境跑满 1-2 个月的策略,不上实盘资金。不是技术问题——是你会发现自己对策略的信任程度完全不够。
-
如果一个策略你不能用三句话讲清楚它赚的是谁的钱,就不要投钱。
每周时间分配
读文档 + 学概念: 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 │ 年化收益/|最大回撤|;越高越好 │
│ 前视偏差 │ 回测中使用了未来信息 → 结果不可信 │
│ 幸存者偏差 │ 只回测现在还活着的股票 → 遗漏了退市的失败者 │
└──────────────┴─────────────────────────────────────────────┘