基于因子的量化选股系统,支持回测、实盘选股和因子研究。
┌─────────────────────────────────────────────────────────────────────────────┐
│ 入口层 (Entry Points) │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────┐ ┌──────────────────┐ ┌────────────────┐ ┌────────────┐ │
│ │run_pipeline.py │ │ run_backtest.py │ │run_backtest. │ │run_live │ │
│ │ (因子研究流水线) │ │ (批量回测) │ │ ipynb │ │ stock.py │ │
│ └───────┬────────┘ └───────┬──────────┘ └───────┬────────┘ └─────┬──────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌───────────────┐ ┌─────────────────────────────────────────────┐ │
│ │pipeline/ │ │ engine.py │ │
│ │orchestrator.py│ │ (统一引擎: 向量化回测 + 实盘选股) │ │
│ │(挖掘→验证→测试)│ └───────────────────────┬─────────────────────┘ │
│ └───────┬───────┘ │ │
│ │ ▼ │
│ │ ┌──────────────────────────────────────┐ │
│ │ │ strategy.py │ │
│ │ │ 因子计算 + 排序 + 权重分配 │ │
│ │ └─────────────────┬──────────────────┘ │
│ │ │ │
│ │ ▼ │
│ │ ┌─────────────────┐ ┌─────────────────┐ │
│ │ │ factor_lib.py │ │ stock_filter.py │ │
│ │ │(119+ 因子+动态注册)│ │ (股票池过滤) │ │
│ │ └─────────────────┘ └─────────────────┘ │
│ │ │
└──────────┼──────────────────────────────────────────────────────────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 数据层 (Data Layer) │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────┐ │
│ │ data_provider.py │ ← 统一数据加载模块(MySQL 访问中枢) │
│ └──────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ MySQL (stockdb) │ │
│ │ daily, daily_basic, moneyflow_ths, index_weight, factor_pool │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
| 文件 | 功能 | 说明 |
|---|---|---|
run_pipeline.py |
因子研究入口 | 统一管理因子注册/挖掘/验证/测试,状态持久化到 MySQL |
run_backtest.py |
批量回测入口 | 配置多组参数运行回测,支持多进程并行,生成详细 txt 报告 |
run_backtest.ipynb |
交互式回测 | Jupyter Notebook 单次回测 |
run_livestock.py |
实盘测试入口 | 测试多个日期的选股结果,生成详细 txt 报告 |
engine.py |
统一引擎 | 向量化回测 + 实盘选股,共享完全相同的数据路径和策略逻辑 |
| 文件 | 功能 | 说明 |
|---|---|---|
strategy.py |
策略核心 | 接收数据 → 计算因子 → 排序 → 返回股票+权重 |
factor_lib.py |
因子库 | 119 个硬编码因子 + 动态注册的 DSL 挖掘因子 |
stock_filter.py |
股票池过滤 | 指数成分股 / 龙虎榜 / 同花顺热榜 / 组合过滤器 |
| 文件 | 功能 | 说明 |
|---|---|---|
data_provider.py |
统一数据加载 | MySQL 访问中枢,提供成交额/换手率/资金流/股票名等查询 |
sql_data_import/ |
数据导入脚本 | Tushare 数据导入 MySQL(支持定时任务/断点续传) |
回测和实盘选股共享统一引擎 engine.py。回测从 MySQL 一次性加载全时段数据,按调仓频率调用 strategy.py,向量化计算组合净值;实盘只做单日选股。两者共享完全相同的数据路径、股票池过滤和策略逻辑。
Python 接口:
from engine import VectorBacktest, BacktestConfig
config = BacktestConfig(
factor_weights={"mined_011": 1.0}, # 因子权重
start_date="20250101",
end_date="20251231",
rebalance_freq="weekly", # "weekly" / "biweekly" / "monthly"
filter_type="index", # 过滤器类型
index_code="000905.SH", # 中证500
portfolio_size=4, # 持仓4只
weight_method="inv_vol", # 反波动率加权
amount_filter_pct=0.2, # 剔除成交额最低20%
turnover_filter_pct=0.2, # 剔除换手率最低20%
commission_rate=0.0003, # 单边佣金 (万三)
slippage_rate=0.0005, # 滑点 (万五)
verbose=True, # 输出调仓进度
debug_selections=True, # 打印每次调仓选股详情
)
result = VectorBacktest(config).run()
# 结果
print(result.metrics) # 年化/回撤/夏普/波动率
print(result.nav) # 每日净值序列
print(result.holdings) # 每次调仓持仓 {date: {stock: weight}}
print(result.rebalance_dates) # 调仓日列表命令行批量回测:
# 顺序执行(输出 backtest_report.txt)
python run_backtest.py
# 多进程并行(多个测试用例时)
python run_backtest.py --parallel
python run_backtest.py --parallel --workers 4Jupyter Notebook:
打开 run_backtest.ipynb,修改配置后运行。
from engine import run_selection, print_selection
result = run_selection(
factor_weights={"mined_011": 1.0},
select_date="20250113", # None=最新交易日
top_n=4,
filter_type="index",
index_code="000852.SH",
weight_method="inv_vol",
)
print_selection(result)
print(result["stocks"]) # ['000001.SZ', '600000.SH', ...]
print(result["weights"]) # {code: weight}命令行(输出 livestock_report_*.txt):
python run_livestock.py| 类型 | 说明 | 参数 |
|---|---|---|
"index" |
仅指数成分股 | index_code: 指数代码 |
"dragon_tiger" |
仅龙虎榜(限制在CSI300/500/1000范围) | lookback, min_net |
"dragon_tiger_index" |
龙虎榜 AND 指数成分股(取交集) | 同时支持以上参数 |
"hot_list" |
同花顺热榜 | hot_list_lookback, hot_list_top_n |
"hot_list_index" |
同花顺热榜 AND 指数成分股(取交集) | 同时支持以上参数 |
None |
不过滤 | - |
示例配置:
# 指数成分股(中证1000)
FILTER_TYPE = "index"
INDEX_CODE = "000852.SH"
# 龙虎榜 + 中证500(取交集)
FILTER_TYPE = "dragon_tiger_index"
INDEX_CODE = "000905.SH"
DRAGON_TIGER_LOOKBACK = 20
DRAGON_TIGER_MIN_NET = 200
# 同花顺热榜 + 指数成分股
FILTER_TYPE = "hot_list_index"
INDEX_CODE = "000852.SH"| 方法 | 说明 |
|---|---|
equal |
等权分配 |
inv_vol |
反波动率加权(低波动股票权重高) |
| 参数 | 默认值 | 说明 |
|---|---|---|
verbose |
False |
每次调仓打印一行进度(日期、净值、收益率、持仓),适合 notebook 交互使用 |
debug_selections |
False |
打印每次调仓的详细选股结果(股票池大小、每只股票的权重和信号值) |
所有因子定义在 factor_lib.py,共 119 个因子:
- alpha1-alpha101(缺 alpha48):WorldQuant Alpha101 因子,共 100 个
- alpha102-alpha120:资金流因子(基于同花顺 moneyflow_ths 数据),共 19 个
常用因子:
| 因子 | 类型 | 说明 |
|---|---|---|
| alpha4 | 动量 | 低成交量排名 |
| alpha42 | 动量 | 高量排名反转 |
| alpha40 | 价值 | 高量下跌 |
| alpha54 | 反转 | 最低价/收盘开盘相关性 |
| alpha106 | 资金流 | 大单vs小单占比差(主力散户分歧) |
Tushare API
│
▼
sql_data_import/ ← 每日 22:45 自动导入
│
▼
MySQL (stockdb)
│
▼
data_provider.py ← 统一数据加载中枢
╱ │ ╲
▼ ▼ ▼
pipeline/ engine.py miners/
data_foundation (统一引擎: (因子挖掘)
.py 回测+选股)
│ │
├──────────────┤
▼ ▼
factor_pool 表 strategy.py ←──── factor_lib.py
(因子状态持久化) (因子计算+排序) (119+ 因子 + DSL 动态注册)
- data_provider.py:统一的 MySQL 数据访问层,回测和实盘共用同一数据路径,提供:
load_stock_history()- 批量加载股票历史行情load_moneyflow_history()- 资金流数据load_amount_snapshot()/load_amount_panel()- 成交额快照/面板load_turnover_rate()/load_turnover_panel()- 换手率数据/面板get_stock_names()- 股票名称get_index_constituents()- 指数成分股get_latest_trade_date()/is_trading_day()/get_nearest_trade_date()- 交易日工具
cd sql_data_import
# 导入全部数据
python -m sql_data_import.daily_import
# 只导入某一项
python -m sql_data_import.daily_import --only stock
python -m sql_data_import.daily_import --only ths_hot
# 安装每日任务(22:45 执行)
./setup_cron.sh install
# 安装每周补漏任务(周六 10:00)
./setup_weekly.sh install
# 查看状态
./setup_cron.sh status
./setup_weekly.sh status| 导入器 | 数据表 | 说明 |
|---|---|---|
importers/stock.py |
stock_basic, daily, top_list | 股票基础信息、日线、龙虎榜 |
importers/index.py |
index_weight, index_daily | 指数成分权重、指数日线 |
importers/moneyflow.py |
moneyflow_ths | 个股资金流向 |
importers/daily_basic.py |
daily_basic | 每日基本面指标 |
importers/ths.py |
ths_index, ths_daily, ths_member | 同花顺概念 |
importers/ths_hot.py |
ths_hot | 同花顺热榜 |
数据库驱动的因子挖掘、验证、测试流水线。所有因子状态持久化到 MySQL factor_pool 表,支持幂等执行。
┌─────────────┐
手写因子 (factor_lib) ─→│ pending_val │←─ AI挖掘 (Train 通过)
└──────┬──────┘
│ Val 筛选
┌────────────┼────────────┐
▼ ▼
┌──────────┐ ┌──────────────┐
│ fail_val │ │ pending_test │
└──────────┘ └──────┬───────┘
│ Test 筛选
┌────────────┼────────────┐
▼ ▼
┌───────────┐ ┌──────┐
│ fail_test │ │ gold │→ 回测/实盘
└───────────┘ └──────┘
全程只看 IC / IC_IR,回测/夏普在筛选完成后才做。
时间划分(固定不可改):
| 数据集 | 时间 | 用途 |
|---|---|---|
| Train | 2018-01-01 ~ 2022-12-31 (5年) | 因子挖掘 + IC 粗筛 |
| Val | 2023-01-01 ~ 2024-06-30 (1.5年) | IC 验证,过滤过拟合 |
| Test | 2024-07-01 ~ 2025-12-31 (1.5年) | IC 终审(黑盒不可调) |
因子 5 状态生命周期(MySQL factor_pool 表):
| 状态 | 含义 | 说明 |
|---|---|---|
pending_val |
待验证 | 手写因子注册时默认进入;挖掘因子 Train 粗筛通过后进入 |
fail_val |
验证失败 | Val 阶段 IC/IR 不达标(过拟合) |
pending_test |
待测试 | Val 通过,等待 Test 最终判定 |
fail_test |
测试失败 | Test 阶段不达标(真实失效) |
gold |
金标池 | 全部达标,可用于实盘和回测 |
筛选阈值:
| 阶段 | IC 阈值 | IR 阈值 | 说明 |
|---|---|---|---|
| Train | ≥0.005 | ≥0.1 | 仅 AI 挖掘用,噪声过滤 |
| Val | ≥0.015 | ≥0.2 | 去过拟合 + 去冗余 |
| Test | ≥0.01 | ≥0.15 | 最终判定(稍宽松避免误杀) |
# ===== 因子流水线入口: run_pipeline.py =====
# 完整流水线: 注册手写因子 + 验证 + 测试 (无挖掘)
python run_pipeline.py
# 完整流水线 + AI 挖掘
python run_pipeline.py --full --mine transformer_rl
# 只注册手写因子 (不验证/测试)
python run_pipeline.py --register
# 只运行验证 (处理所有 pending_val 因子)
python run_pipeline.py --validate
# 只运行测试 (处理所有 pending_test 因子)
python run_pipeline.py --test
# 单轮 AI 挖掘 (自动 Train粗筛 + Val验证 + Test测试)
python run_pipeline.py --mine transformer_rl --train-steps 600
# 多轮持续挖掘 (热启动, 模型越训越聪明)
python run_pipeline.py --mine transformer_rl --rounds 50 --train-steps 600
# 推荐: 大 batch + 多轮 + 更多候选
python run_pipeline.py --mine transformer_rl --rounds 100 --train-steps 600 --batch-size 256 --top-n 30
# 查看因子池状态
python run_pipeline.py --status
# 生成报告
python run_pipeline.py --report持续挖掘 (--rounds): 指定 --rounds N 时启用多轮热启动模式。模型在多轮之间保持权重继续训练,数据只加载一次,黑名单每轮刷新(上一轮失败的公式不会再被探索),因子编号全局递增不冲突。每轮结束自动执行验证+测试。
幂等特性: 已处理过的因子不会重复计算。例如 gold 因子再次运行 --validate 时会被跳过。如需重新验证,在 MySQL 中手动将 status 改回 pending_val 即可。
from pipeline.orchestrator import Pipeline
pipe = Pipeline()
pipe.prepare_data() # 加载数据(自动缓存到 Parquet)
# Flow 1: 注册手写因子 → pending_val
pipe.run_handcoded()
# Flow 2a: 单轮 AI 挖掘 → Train 粗筛 → pending_val → 自动 Val + Test
pipe.run_mining("transformer_rl", train_steps=600, batch_size=256)
# Flow 2b: 多轮持续挖掘(热启动, 模型越训越聪明)
pipe.run_mining_rounds("transformer_rl", rounds=50, train_steps=600, batch_size=256)
# Flow 3: 批量验证 pending_val → pending_test / fail_val
pipe.run_validation()
# Flow 4: 批量测试 pending_test → gold / fail_test
pipe.run_testing()
# 或者一步全跑(注册 + 验证 + 测试, 可选挖掘)
pipe.run_full()在因子通过 gold 认证后,进行深度分析(仅使用 Test 数据),结果写入 factor_analysis 表:
# 分析所有 gold 因子 (跳过已分析的)
python run_pipeline.py --analyze
# 强制重新分析
python run_pipeline.py --analyze --force
# 分析指定因子
python run_pipeline.py --analyze --factor-ids mined_011 mined_025from pipeline.deep_analysis import DeepAnalyzer
analyzer = DeepAnalyzer()
analyzer.run() # 分析所有 gold
analyzer.run(factor_ids=["mined_011"]) # 指定因子
analyzer.run(force=True) # 强制重新分析4 项分析内容:
- 分层回测 + 单调性: Q1~Q5 累计收益、多空年化、单调性得分 [-1, 1]
- IC 衰减曲线: 1/2/3/5/10 天前瞻 IC 均值
- 多空净值 + 最大回撤: long-short 累计净值的最大回撤
- 月度 IC 分布: 每月 IC 均值、胜率、最差/最佳月
| 模块 | 功能 |
|---|---|
run_pipeline.py |
命令行入口(注册/挖掘/验证/测试/报告,支持 --rounds 多轮热启动) |
pipeline/config.py |
时间划分、阈值、状态常量、股票池配置 |
pipeline/data_foundation.py |
数据加载、Parquet 缓存、年度 CSI500 成分股 |
pipeline/ic_evaluator.py |
统一 IC/IR 计算 |
pipeline/factor_pool.py |
因子池管理(MySQL 后端,5 状态生命周期,全局编号) |
pipeline/screener.py |
Val/Test IC 筛选 + 去冗余 |
pipeline/orchestrator.py |
流水线控制器(DB 驱动、幂等执行、多轮热启动挖掘) |
pipeline/report.py |
报告生成 |
pipeline/deep_analysis.py |
Gold 深度分析(分层回测、IC 衰减、多空回撤、月度 IC,结果写入 factor_analysis 表) |
| 引擎 | 模块 | 说明 |
|---|---|---|
| Transformer+RL | miners/transformer_rl/ |
Transformer 自回归生成 DSL 因子公式 + REINFORCE 优化 |
| (预留) | miners/gp/ |
遗传规划 |
挖掘引擎是有状态的:模型权重和特征缓存保存在实例上。多轮挖掘时模型热启动(在上一轮权重基础上继续训练),每轮的 best_formulas 从空开始(旧的好公式已在 DB 中),黑名单每轮从 DB 刷新。
新增挖掘引擎只需实现 MinerBase 接口(miners/base.py),引擎产出的 DSL 因子通过 miners/formula_compiler.py 编译为 DataFrame 函数,自动注册到 factor_lib.py,可直接用于 engine.py(回测和实盘选股)。
挖掘参数说明:
| 参数 | 默认值 | 说明 |
|---|---|---|
--rounds |
1 | 挖掘轮数,>1 启用多轮热启动模式 |
--train-steps |
300 | 每轮训练步数(REINFORCE 迭代次数) |
--batch-size |
128 | 每步生成的公式数量 |
--top-n |
20 | 每轮保留的最优候选公式数 |
因子池持久化到 MySQL stockdb.factor_pool 表,表结构包括:
| 字段 | 说明 |
|---|---|
factor_id |
因子 ID(如 alpha40, mined_003) |
name |
因子名称 |
source |
来源(handcoded / transformer_rl / gp 等) |
formula |
DSL 公式(仅挖掘因子) |
status |
5 状态之一(pending_val / fail_val / pending_test / fail_test / gold) |
train_ic/ir/win_rate/t_stat/n_days |
Train 阶段 IC 统计 |
val_ic/ir/win_rate/t_stat/n_days |
Val 阶段 IC 统计 |
test_ic/ir/win_rate/t_stat/n_days |
Test 阶段 IC 统计 |
formula_fingerprint |
公式指纹(去重用) |
tokens |
公式 token 列表(JSON) |
metadata |
扩展元数据(JSON) |
pandas
numpy
pymysql
sqlalchemy
scipy
tushare
torch # AI 因子挖掘 (Transformer+RL)
# MySQL
export MYSQL_HOST=localhost
export MYSQL_PORT=3306
export MYSQL_USER=root
export MYSQL_ROOT_KEY=your_password
# Tushare
export TUSHARE_TOKEN=your_token| 表名 | 说明 |
|---|---|
daily |
日线数据 (ts_code, trade_date, open, high, low, close, vol, amount) |
daily_basic |
每日指标 (ts_code, trade_date, turnover_rate, ...) |
index_weight |
指数成分股权重 (index_code, con_code, trade_date, weight) |
top_list |
龙虎榜数据 (ts_code, trade_date, net_amount, ...) |
stock_basic |
股票基础信息 (ts_code, name, ...) |
moneyflow_ths |
个股资金流向 (ts_code, trade_date, net_amount, buy_lg_amount, ...) |
ths_hot |
同花顺热榜 (ts_code, trade_date, rank, ...) |
factor_pool |
因子池(factor_id, status, IC 统计, 公式, 元数据) |
quantum_code/
├── README.md # 本文档
├── run_pipeline.py # ★ 因子流水线入口(注册/挖掘/验证/测试,支持 --rounds 持续挖掘)
├── run_backtest.py # 批量回测入口(支持 --parallel 多进程,输出 txt 报告)
├── run_backtest.ipynb # 交互式回测(Jupyter Notebook)
├── run_livestock.py # 实盘测试入口(输出 txt 报告)
│
├── engine.py # ★ 统一引擎(向量化回测 + 实盘选股)
├── data_provider.py # 统一数据加载模块(MySQL 访问中枢)
├── strategy.py # 策略核心
├── factor_lib.py # 因子库(119+ 因子,支持动态注册 DSL 因子)
├── stock_filter.py # 股票池过滤(指数/龙虎榜/热榜/组合)
│
├── pipeline/ # ★ 因子研究流水线(DB 驱动)
│ ├── config.py # 时间划分、阈值、5 状态常量、股票池配置
│ ├── data_foundation.py # 数据加载、Parquet 缓存、CSI500 年度股票池
│ ├── ic_evaluator.py # 统一 IC/IR 计算
│ ├── factor_pool.py # 因子池管理(MySQL 后端, 5 状态 + 全局编号 + 黑名单)
│ ├── screener.py # Val/Test IC 筛选 + 去冗余
│ ├── orchestrator.py # 流水线控制器(幂等执行、多轮热启动挖掘)
│ ├── report.py # 报告生成
│ ├── deep_analysis.py # Gold 深度分析(分层回测、IC 衰减、多空回撤、月度 IC → DB)
│ ├── cache/ # Parquet 缓存数据
│ └── results/ # 输出结果(pipeline_report.txt, deep_analysis_report.txt 等)
│
├── miners/ # ★ 可插拔挖掘引擎
│ ├── base.py # 抽象接口 MinerBase + CandidateFactor
│ ├── formula_compiler.py # DSL 公式 → DataFrame 函数编译器
│ └── transformer_rl/ # Transformer + REINFORCE 引擎
│ ├── config.py # 训练配置
│ ├── features.py # 特征工程(8 个基础特征 F0-F7)
│ ├── ops.py # 操作符定义(12 个)
│ ├── vm.py # Stack VM(公式执行引擎)
│ ├── model.py # AlphaGPT(Transformer 模型)
│ ├── scorer.py # 因子评分(训练奖励信号)
│ └── engine.py # 训练引擎(有状态, 支持热启动, 实现 MinerBase)
│
├── sql_data_import/ # 数据导入
│ ├── daily_import.py # 每日导入主脚本
│ ├── weekly_repair.py # 每周补漏脚本
│ ├── config.py # 全局配置
│ ├── db.py # 数据库工具
│ ├── tables.py # 表结构定义(含 factor_pool DDL)
│ ├── checkpoint.py # 断点续传管理
│ ├── importers/ # 各数据导入器
│ └── README.md # 数据导入说明
│
└── .venv/ # Python 虚拟环境(不提交)
- 统一引擎:
engine.py整合了回测和实盘选股,通过data_provider.py访问 MySQL,共享完全相同的数据加载路径、股票池过滤和策略逻辑,确保回测与实盘的一致性。 - 向量化回测:引擎一次性加载全时段面板数据,按调仓频率切片调用策略,向量化计算组合净值,包含佣金和滑点模型。
- 股票池范围:龙虎榜过滤后会限制在 CSI300/500/1000 历史成分股范围内。
- 过滤顺序:先过滤股票池 → 再过滤成交额/换手率 → 最后计算因子排序。
- 定时任务:数据导入在每天 22:45 自动执行,确保所有数据(含同花顺热榜 22:30 更新)已就绪。
- 因子流水线幂等:
run_pipeline.py的所有操作均为幂等——已经验证/测试过的因子不会重复计算。如需重新处理某个因子,在 MySQLfactor_pool表中手动修改其status即可。 - DSL 因子注册:挖掘引擎产出的 DSL 因子通过
factor_lib.register_factor()动态注册,回测和实盘可直接使用,无需手动添加代码。 - 持续挖掘:使用
--rounds N启动多轮热启动挖掘,模型权重跨轮保持,因子编号全局递增(mined_008,mined_009, ...),黑名单每轮刷新。可在 tmux/screen 中长期运行。