写给只会 Python、做 Agent/RAG、没接触过量化的你。读完这份文档,你不仅能理解这个项目在做什么,还能跟面试官聊量化。
- 什么是量化交易
- Python 在量化中干什么
- 量化核心概念速成
- 多因子模型:量化的心脏
- 本项目全貌
- 开发思路:我是怎么一步步搭出来的
- 逐模块详解
- 动手跑起来
- 面试怎么说
- 从 Agent 到 Quant:你的优势
用量化模型代替人做投资决策。
传统投资:基金经理看财报、看新闻、凭经验决定买什么卖什么。 量化投资:用数学模型分析数据,计算机自动生成买卖信号。
很多人以为量化就是"毫秒级抢单"。其实量化分很多种:
| 类型 | 持仓周期 | 典型策略 | 我们的项目 |
|---|---|---|---|
| 高频 (HFT) | 毫秒~分钟 | 做市、套利 | ❌ 不做 |
| 日内 | 分钟~小时 | 趋势跟踪 | ❌ 不做 |
| 中频 | 天~周 | 多因子选股 | ✅ 就是这个 |
| 低频 | 月~季度 | 资产配置 | 部分涉及 |
我们的项目是月频多因子选股:每个月调一次仓,选一批股票持有,下个月再换。
你做 Agent/RAG,本质是:
用户输入 → 检索 → 推理 → 生成回答
量化交易:
市场数据 → 因子计算 → 信号合成 → 生成持仓
结构几乎一样!你已有的 Python 技能完全可迁移。
| 环节 | Python 库 | 对应你的 Agent 经验 |
|---|---|---|
| 数据获取 | tushare, akshare | 类似调 API 拿数据 |
| 数据处理 | pandas, numpy | 跟你的数据处理一样 |
| 科学计算 | scipy, numba | 类似向量计算优化 |
| 优化求解 | cvxpy | 类似约束求解 |
| 可视化 | matplotlib, seaborn | 画图表 |
| LLM 调用 | openai | 你的主场! |
| 回测框架 | 本项目自研 | 类似测试框架 |
- pandas 处理表格数据极快 — 500只股票×5年数据 = 几十万行,pandas 一行代码搞定
- 生态丰富 — 从数据到机器学习到可视化都有库
- 快速迭代 — 研究阶段不需要 C++ 的性能,需要的是"试错速度"
- 跟你的技能栈重合 — 你做 RAG 用的那些库,量化也在用
最基础的概念。如果今天股价 10 元,明天 10.5 元:
日收益率 = (10.5 - 10) / 10 = 0.05 = 5%
在 Python 里:
returns = prices.pct_change() # pandas 一行搞定因子就是"预测股票涨跌的特征"。 你是做 Agent 的,把因子类比成 RAG 的 embedding 或检索特征——它们都是用来做预测的输入信号。
举个例子:
- 动量因子:"过去一个月涨得好的股票,下个月继续涨" → 计算过去 21 天收益率
- 价值因子:"市盈率低的股票,长期收益更高" → 计算 PE 的倒数
- 波动率因子:"波动大的股票,风险调整后收益更差" → 计算标准差
每个因子就是一个数字,每只股票每天有一个值。
衡量因子好不好用的指标。 一句话:因子值跟未来收益率的相关性。
IC = correlation(今天的因子值, 明天的收益率)
- IC > 0.03:好因子,有预测力
- IC ≈ 0:没啥用
- IC < 0:反向指标(做空能赚钱)
类比:IC 就像 RAG 的 retrieval precision——衡量你检索出来的文档跟问题的相关性。
跑赢市场的那部分收益。 比如大盘涨了 5%,你的策略涨了 8%,那 3% 就是 alpha。
量化研究员的核心工作就是寻找 alpha——找到能稳定预测收益的因子。
用历史数据模拟策略表现。 不能用未来数据预测过去(这叫"未来函数",量化界的死罪)。
回测 = 假设我在 2021 年用这个策略交易,到 2025 年能赚多少?
类比:就像你用测试集评估 RAG 系统——用没见过的数据测效果。
最常用的策略评价指标。 一句话:每承担一单位风险,赚了多少收益。
Sharpe = 年化收益率 / 年化波动率
- Sharpe > 1:不错的策略
- Sharpe > 2:很好的策略
- Sharpe > 3:要么是天才,要么有 bug
策略从最高点跌到最低点的幅度。 比如本金从 100 万跌到 80 万,最大回撤就是 20%。
面试官最爱问:"最大回撤多少?怎么控制?"
用多个因子综合打分,选出最好的股票。
类比你的 RAG 系统:
- RAG:多个检索源(向量检索 + BM25 + 知识图谱)→ 融合排序 → 返回结果
- 多因子:多个因子(动量 + 价值 + 波动率...)→ ICIR 加权合成 → 股票排名
原始数据 (价格/财务)
↓
计算 15 个因子 (每只股票每天 15 个特征)
↓
因子处理 (缩尾去极值 → 标准化 → 行业中性化)
↓
IC 评估 (看每个因子的预测力)
↓
ICIR 加权合成 (预测力强的因子权重大)
↓
横截面排名 (在同一天的所有股票中排名)
↓
最终信号 [-0.5, 0.5] (越大越好)
比如说你发现"银行股最近因子值都高",但这可能只是因为银行股整体涨了,而不是因子本身好。行业中性化就是剔除行业的影响,让因子反映的是个股自身的特征。
类比你的 RAG:如果检索结果全是某个特定来源的文档,你需要做 source diversification。
A 股有很多你在美股看不到的规则:
- 涨跌停 ±10%(ST 股票 ±5%):涨停买不到,跌停卖不掉
- T+1:今天买的明天才能卖(美股是 T+0)
- 印花税:卖股票时收 0.1%(美股没有)
- 停牌:公司有重大事项可以停牌几天甚至几个月
- ST 股票:连续亏损被特殊处理的股票,很多机构不能买
- 手数限制:最少买 100 股(1 手)
这些在我们的项目中全部处理了。面试官问你"回测跟实盘有什么区别",你就可以一条条讲。
A 股多因子量化研究平台:从数据到回测的完整流水线。
┌─────────────────────────────────────────────────────────────┐
│ config/default.yaml │
│ (所有参数:500只股票/月频调仓/5%仓位上限...) │
└──────────────────────────┬──────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────┐
│ ① Data Layer ② Factor Engine ③ Alpha Model │
│ 数据获取+清洗 计算15个因子 因子合成→信号 │
│ - Synthetic生成器 - 动量/波动/RSI... - 等权/IC/ICIR │
│ - Tushare实盘 - 缩尾/标准化/中性化 - 排名归一化 │
│ - 停牌/ST/复权 - IC评估 - 输出: signal │
└──────────────────────────┬───────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────┐
│ ④ Portfolio ⑤ Backtest ⑥ Report │
│ 组合优化 回测引擎 报告生成 │
│ - 等权/MVO/风险平价 - 月频调仓 - 净值曲线 │
│ - 协方差估计 - 成本扣除 - 回撤分析 │
│ - 行业+换手约束 - 持仓漂移 - 因子排名 │
└──────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────┐
│ ⑦ Risk Module (横跨): VaR/CVaR/压力测试/行业暴露 │
│ ⑧ Agent Module (横跨): LLM情感因子集成 │
└──────────────────────────────────────────────────────────────┘
quant_platform/
├── main.py # CLI 入口(6个命令)
├── config/default.yaml # 所有参数
│
├── data/ # ① 数据层
│ ├── providers/synthetic.py # 合成数据生成器(不用联网就能跑)
│ ├── providers/tushare_loader.py # 实盘数据(需要 token)
│ └── pipeline.py # 数据清洗流水线
│
├── factors/ # ② 因子引擎
│ ├── technical.py # 10个技术因子
│ ├── fundamental.py # 5个基本面因子
│ ├── processing.py # 因子处理(缩尾/标准化/中性化)
│ └── evaluation.py # 因子评估(IC/ICIR)
│
├── alpha/ # ③ Alpha 模型
│ └── pipeline.py # 因子合成→信号
│
├── portfolio/ # ④ 组合优化
│ └── optimizers.py # 3种优化器
│
├── backtest/ # ⑤ 回测引擎
│ ├── engine.py # 核心回测逻辑
│ ├── cost_model.py # A股成本模型
│ └── metrics.py # 业绩指标计算
│
├── risk/ # ⑦ 风险管理
│ ├── var.py # VaR/CVaR
│ └── stress.py # 压力测试
│
├── reporting/ # ⑥ 报告
│ └── dashboard.py # 文本+图表仪表盘
│
├── agent/ # ⑧ LLM 模块(你的主场!)
│ └── sentiment_factor.py # 情感因子
│
├── utils/ # 工具
│ ├── numba_accelerator.py # Numba JIT 加速
│ └── cache.py # 流水线缓存
│
├── notebooks/
│ └── research_workflow.ipynb # Jupyter 研究流程
│
└── tests/ # 1077 个测试
| 指标 | 数值 |
|---|---|
| 股票数 | 500 只(可调) |
| 历史数据 | 5 年 (2021-2025) |
| 交易日 | ~1300 天 |
| 因子数 | 15 个标准 + 1 个 LLM |
| 优化器 | 3 种 |
| 单元测试 | 1077 个 |
| CLI 命令 | 6 个 |
| 代码行数 | ~40,000 行 |
- 先跑通再优化:先让整个流水线跑起来,哪怕因子很烂、回测很慢
- 配置驱动:没有硬编码,所有参数在 YAML 里
- 接口抽象:用 ABC 定义接口,方便切换数据源/优化器
- 有测试:每写一个模块就写测试,防止后面改崩
Step 1: 数据层
问题:没数据什么都干不了
方案:先做 SyntheticDataProvider(合成数据),再做 TushareProvider(实盘)
关键:合成数据要够真实——要有行业、停牌、涨跌停、复权
Step 2: 因子引擎
问题:怎么从价格算出有用的信号
方案:先写 BaseFactor ABC,然后逐个实现技术因子和基本面因子
关键:因子处理流水线(缩尾→标准化→中性化),这是量化的标准操作
Step 3: Alpha 模型
问题:15 个因子怎么合成一个信号
方案:ICIR 加权——预测力强的因子权重高
关键:横截面排名归一化到 [-0.5, 0.5]
Step 4: 组合优化
问题:有了信号,具体买哪些股票、各买多少
方案:先做最简单的等权,再做 MVO 和风险平价
关键:约束条件(不能买太多同一行业、换手不能太高)
Step 5: 回测引擎
问题:模拟历史表现
方案:向量化回测——每月调仓,扣费,计算日收益
关键:A 股成本模型(佣金 0.03% + 印花税 0.1% + 滑点)
Step 6: 报告
问题:怎么展示结果
方案:文本仪表盘 + 4 张图表 + CSV 导出
Step 7: 锦上添花
- Numba 加速(5个计算内核 5-20x 提速)
- LLM 情感因子(你的 RAG 经验直接能用!)
- Pipeline 缓存(不重复计算)
- 策略对比/参数搜索
Q: 为什么用向量化回测而不是事件驱动? A: 事件驱动适合高频,我们做月频多因子,向量化更简单更快。一个月就调一次仓,不需要模拟每一笔订单。
Q: 为什么默认用合成数据? A: 不用联网、不用注册 API、可复现。面试官让你当场跑一下,Tushare 没 token 就尴尬了。合成数据现在内置了 alpha 结构(IC~0.04),演示效果真实。
Q: 为什么要做因子中性化? A: 不做中性化的话,你的"好股票"可能只是某个行业的股票——你不是在选股,是在选行业。
干了什么:生成或获取 A 股数据,清洗成可用的格式。
SyntheticDataProvider(合成数据):
# 生成 500 只股票、5 年的日频数据
# 包含:开高低收价格、成交量、换手率、复权因子
# 三因子模型:收益 = 市场因子 + 行业因子 + 个股异质因子
# 内置 alpha 结构:动量效应让过去涨的股票未来继续涨一点DataPipeline(数据清洗):
# 1. 过滤 ST 股票(连续亏损的风险股)
# 2. 过滤未上市/已退市股票(幸存者偏差!)
# 3. 处理停牌(短期停牌前向填充,长期停牌剔除)
# 4. 复权价格计算(close_adj = close / adj_factor)
# 5. 日收益率计算(returns = close_adj.pct_change())TushareProvider(实盘数据):
# 需要免费注册 tushare.pro 获取 token
# 拉到 CSI 300 成分股的前复权日频数据
# 存到 HDF5 本地缓存,下次秒加载
# 没有 token 时自动回退到合成数据10 个技术因子(从价格和成交量算出):
| 因子名 | 含义 | 怎么算 |
|---|---|---|
| momentum_1m | 1月动量 | 过去21天累计收益 |
| momentum_3m | 3月动量 | 过去63天累计收益 |
| momentum_6m | 6月动量 | 过去126天累计收益 |
| momentum_12m | 12月动量 | 过去252天(跳过最近21天) |
| volatility_20d | 20日波动 | 日收益率的标准差 |
| volatility_60d | 60日波动 | 同上,更长窗口 |
| turnover_20d | 换手率 | 20日平均换手率 |
| rsi_14d | RSI | 相对强弱指数 (0-100) |
| macd | MACD | 指数平滑异同移动平均线 |
| amplitude_20d | 振幅 | 20日平均(高-低)/收盘价 |
5 个基本面因子(从财务报表算出):
| 因子名 | 含义 |
|---|---|
| log_market_cap | 对数市值(规模因子) |
| pb_ratio | 市净率(价值因子) |
| pe_ratio | 市盈率(价值因子) |
| roe | 净资产收益率(质量因子) |
| asset_growth | 资产增长率(成长因子) |
因子处理流水线(每天横截面做一遍):
原始因子值
↓
缩尾 (Winsorize): 把极端值拉到 1%/99% 分位数
↓
标准化 (Standardize): (值 - 均值) / 标准差 → 均值0方差1
↓
中性化 (Neutralize): 回归掉行业+市值的影响 → 取残差
↓
干净因子值
类比你的 RAG:因子处理就像对检索结果做 normalization + diversification。
3 种合成方法:
# 1. 等权:所有因子平均
signal = (factor1 + factor2 + ... + factor15) / 15
# 2. IC 加权:IC 高的因子权重高
weight_i = IC_i / sum(所有IC)
signal = weight_1 * f1 + weight_2 * f2 + ...
# 3. ICIR 加权:IC 稳定(ICIR 高)的因子权重高
weight_i = ICIR_i / sum(所有ICIR)
signal = weight_1 * f1 + weight_2 * f2 + ...
# (这是默认方法,因为稳定性也很重要)最后做横截面排名归一化到 [-0.5, 0.5]:在所有股票中排名,排名最高的给 0.5,最低的给 -0.5。
3 种优化器:
| 优化器 | 思路 | 快慢 |
|---|---|---|
| EqualWeight | 信号最前的 N 只股票各买 1/N | 极快 |
| MeanVariance | 最大化 收益 - 风险厌恶 × 风险 | 慢(cvxpy求解) |
| RiskParity | 每只股票贡献相同的风险 | 慢(cvxpy求解) |
约束条件(模拟真实交易限制):
- 纯多头:不能做空
- 单票 ≤ 5%
- 单行业 ≤ 30%
- 月度换手 ≤ 30%
- 最少买 100 股
每月调仓流程:
月末最后一天:
1. 计算信号(哪个股票好)
2. 估计协方差(股票之间的相关关系)
3. 优化器算出目标权重
4. 记录这次调仓
月初第一天:
5. 按目标权重买入(扣除佣金)
持有期间:
6. 权重随价格漂移(涨得多的占比变大)
7. 每天记录组合收益率
下个月末:
8. 计算换手(哪些要卖、哪些要买)
9. 扣除印花税(0.1%,仅卖出)+ 滑点
10. 重复 1-9
成本模型(A 股真实费率):
- 佣金:0.03% 双边(买和卖都收)
- 印花税:0.1% 单边(只卖的时候收)
- 滑点:0.1%(实际成交价可能比预期差一点)
VaR (Value at Risk):在 95% 置信度下,一天最多亏多少。三种算法:
- 历史模拟法:看历史最差的 5% 天亏了多少
- 参数法:假设收益服从正态分布,用公式算
- 蒙特卡洛:模拟 10 万条路径,看分布
CVaR (Expected Shortfall):如果亏得比 VaR 还多,平均亏多少。
压力测试:模拟极端行情——
- 2008 全球金融危机
- 2015 年 A 股股灾
- 2020 年新冠崩盘
这是最接近你 Agent/RAG 经验的模块。
架构:
LLMSentimentFactor (继承 BaseFactor)
│
├── SentimentAnalyzer (Strategy 模式,可切换)
│ ├── KeywordAnalyzer (默认,零成本,关键词打分)
│ └── OpenAIAnalyzer (真实 API,GPT-4o-mini)
│
├── 30 条中文财经标题模板
│ ├── 看涨:净利润同比增长50%、获得大额订单...
│ ├── 看跌:大股东减持、收到监管问询函...
│ └── 中性:公布定期报告、召开股东大会...
│
└── JSON 本地缓存 (避免重复调用 LLM)
怎么工作:
- 每只股票每天随机生成 0-2 条财经标题(模拟新闻流)
- 用情感分析器给每条标题打分(-1 = 极度看空,+1 = 极度看多)
- 取平均作为当天该股票的情感因子值
- 这个因子跟其他 15 个因子一起进入 alpha 模型
你怎么扩展:
- 接入真实的新闻 API(东财、同花顺)
- 用你自己的 RAG pipeline 做新闻聚合
- 替换成你微调的模型
- 加入多模态(分析财报图表)
这个模块的价值:面试官看到"LLM + Quant"会立刻提起兴趣。这是你的差异化优势。
Numba JIT 加速:把 Python 函数编译成机器码。
# 正常 Python/Pandas: 5 秒
# Numba JIT 编译后: 0.3 秒
# 加速比: ~17x5 个被加速的计算内核:
- 滚动累计收益(动量因子核心)
- 最大回撤计算
- 横截面缩尾
- Spearman Rank IC
- Ledoit-Wolf 协方差收缩
每个都有 Pandas + Numba 双实现,Numba 不可用时自动回退。
cd quant_platform
pip install -r requirements.txt# 用合成数据跑完整流水线(不需要任何 API key)
python main.py run --force你会看到:
- 生成 500 只股票的 5 年数据
- 计算 15 个因子并评估 IC
- 合成 alpha 信号
- 优化持仓权重
- 回测并输出报告
输出示例(简化):
======================================================================
QUANTITATIVE STRATEGY BACKTEST — DASHBOARD
======================================================================
--- PERFORMANCE ---
Total Return: 45.23%
Annual Return: 8.15%
Sharpe Ratio: 1.45
Max Drawdown: -12.30%
--- FACTOR IC RANKINGS ---
+ momentum_1m IC=+0.0418 ICIR=+2.11
+ rsi_14d IC=+0.0402 ICIR=+2.05
...
--- STRESS TESTS ---
2008 Crisis: -8.2% cumulative, max DD -15.1%
2015 Crash: -12.5% cumulative, max DD -18.3%
======================================================================
# 策略对比(同时测 3 个优化器)
python main.py compare
# 参数网格搜索
python main.py sweep
# 运行测试
pytest tests/ -v
# 查看缓存
python main.py cache listjupyter notebook notebooks/research_workflow.ipynb6 步完整研究流程,每一步都有图表。
"我做了一个 A 股多因子量化研究平台。端到端流水线从数据到回测,500 只股票 5 年数据,15 个因子,3 种优化器。1077 个单元测试。特色是 Numba JIT 加速、LLM 情感因子集成、10 个 A 股实盘陷阱全处理。还写了策略对比和参数搜索的 CLI 工具。"
Q: 你的回测跟实盘有什么区别?
"我处理了 10 个 A 股特有的实盘陷阱:前复权、停牌、幸存者偏差、涨跌停、ST 过滤、T+1、佣金印花税、手数限制、除权除息、行业漂移。没有做的是高频 order-book 级别的流动性建模,但对月频多因子策略这不是瓶颈。"
Q: IC 是什么意思?为什么重要?
"Information Coefficient,因子值跟未来收益的秩相关系数。IC > 0.03 说明因子有预测力。为什么用 Rank IC 而不是 Pearson IC?因为 Rank IC 对异常值不敏感,更稳健。"
Q: 你怎么防止过拟合?
"1) 因子只有 15 个,没有做因子挖掘(没有挖几万个因子然后挑显著的);2) 因子经济逻辑清晰——动量、价值、波动率都有学术支撑;3) ICIR 加权——不仅看 IC 大小还看稳定性;4) 横截面中性化防止了行业和市值的虚假相关。"
Q: 你怎么做 LLM 集成的?
"写了一个 LLMSentimentFactor,继承 BaseFactor。用 Strategy 模式隔离了分析器:默认用关键词打分(零成本),可以切换到 OpenAI API。有 JSON 缓存避免重复调用。这个因子跟传统 15 个因子一起进入 alpha 流水线。"
(这是你的强项,可以展开聊 RAG pipeline 怎么改造)
Q: 为什么不直接用现有的回测框架(backtrader/zipline)?
"两个原因:1) 面试看的是你懂不懂底层原理,用框架体现不出;2) A 股有特殊规则,通用框架不一定支持(比如印花税单边征收、手数限制、涨跌停)。自研引擎虽然简单但完全掌控。"
如果面试官发现你的策略 Sharpe 不高或回测有问题:
"合成数据的 IC 在 0.04 左右,这是真实可信的水平。实盘 A 股多因子策略的 Sharpe 一般在 1-2 之间。超过 3 要么是天才要么有过拟合。MVO 优化器在股票数多的时候会用等权回退——这是工程上的诚实处理,不是把崩溃藏起来。"
| Agent/RAG 技能 | 量化对应 |
|---|---|
| Python 数据处理 | pandas 操作股价数据 |
| API 调用 | Tushare / OpenAI API |
| 检索管道 | 因子计算流水线 |
| 结果排序 | Alpha 信号排名 |
| 评估指标 | IC / Sharpe / 回撤 |
| LLM Prompt 工程 | 情感分析 prompt |
| 缓存策略 | 情感因子 JSON 缓存 |
| 向量搜索 | 协方差矩阵运算 |
| 系统架构设计 | 模块化量化平台 |
"我主要做 Agent 和 RAG,这个量化项目是我为了面试自学的。我从零搭了一个完整的量化研究平台,把 LLM 集成进去做情感因子。我发现量化跟 RAG 的系统设计思路很像——都是数据流水线 + 特征工程 + 模型融合 + 评估。我的差异化优势是能把 AI 技术(比如 LLM)应用到量化选股里。"
- 用你的 RAG pipeline 替换模拟新闻:接真实新闻 API → 检索 → LLM 打分
- 加入多模态:分析财报 PDF、K 线图
- Agent 化:让 LLM 自动分析回测结果,生成归因报告
- 微调模型:用你自己的数据微调一个金融情感分析模型
| 术语 | 英文 | 一句话解释 |
|---|---|---|
| 因子 | Factor | 预测股票涨跌的特征 |
| IC | Information Coefficient | 因子预测力的指标,>0.03 算好 |
| ICIR | IC / std(IC) | IC 的稳定性,越高越稳定 |
| Alpha | Alpha | 跑赢市场的那部分收益 |
| Beta | Beta | 跟市场一起波动的那部分收益 |
| Sharpe | Sharpe Ratio | 收益/风险,>1 算不错 |
| 回撤 | Drawdown | 从最高点跌了多少 |
| 中性化 | Neutralize | 剔除行业/市值等干扰因素 |
| 缩尾 | Winsorize | 把极端值拉到合理范围 |
| 复权 | Price Adjustment | 修正分红配股导致的价格跳空 |
| 幸存者偏差 | Survivorship Bias | 只看活着的股票忽略退市的 |
| 前视偏差 | Look-ahead Bias | 用未来数据预测过去(死罪) |
| MVO | Mean-Variance Optimization | 均值方差优化 |
| VaR | Value at Risk | 在险价值:最大可能亏损 |
| CVaR | Conditional VaR | 条件在险价值:极端情况平均亏损 |
这份指南的目标是让你不仅能理解这个项目,还能跟量化面试官自信地对话。
你是做 Agent/RAG 的——量化交易的信号流水线跟你每天写的检索管道本质上是同一套系统设计思路。相信自己。