A-share quantitative research pipeline: data ingestion -> panel construction -> backtesting
本项目当前是一套以 A 股日频研究 为主的量化工程仓库,核心目标不是做完整生产系统,而是把研究常用的数据准备、面板构建、策略回测和结果导出做成一条可复现、可测试、可扩展的闭环。
当前主链路已经明确:
- 从 TuShare 拉取原始数据
- 构建 HS300 研究面板
- 运行示例策略与因子分组测试
- 输出标准化结果和质量检查报表
这个仓库当前主要服务两个场景:
- A 股研究原型验证:快速验证因子、价格列、调仓频率、简单交易成本假设
- 工程化研究底座:避免 notebook-only 工作流,把数据和回测流程固化成脚本与可测试模块
当前不是完整的生产交易系统,尤其在以下方面仍是研究级实现:
- 股票池已支持 动态 HS300 成分历史过滤,但默认研究口径仍偏单指数日频研究
stock_st下载链路已接入;若 TuShare 账号无权限,会保留空占位文件并降级运行- 回测引擎偏向最小可用闭环,尚未覆盖更复杂的订单撮合与风控约束
quant/
├── config/
├── src/
│ ├── quantcore/
│ │ ├── paths.py
│ │ ├── schema.py
│ │ └── __init__.py
│ ├── quantbt/
│ │ ├── engine.py
│ │ ├── metrics.py
│ │ ├── cost.py
│ │ ├── io.py
│ │ └── __init__.py
│ ├── markets/
│ │ ├── a_share/
│ │ │ ├── data/
│ │ │ ├── providers/
│ │ │ ├── research/
│ │ │ ├── cli/
│ │ │ ├── paths.py
│ │ │ ├── schema.py
│ │ │ ├── universe.py
│ │ │ └── __init__.py
│ │ ├── crypto/
│ │ │ ├── data/
│ │ │ ├── providers/
│ │ │ ├── research/
│ │ │ ├── cli/
│ │ │ ├── paths.py
│ │ │ └── __init__.py
│ │ └── futures/
│ │ ├── data/
│ │ ├── providers/
│ │ ├── research/
│ │ ├── cli/
│ │ ├── instruments.py
│ │ ├── paths.py
│ │ ├── schema.py
│ │ └── __init__.py
│ ├── quanta_stock/ # 兼容层,后续可移除
│ └── quantcrypto/ # 兼容层,后续可移除
├── tests/
│ └── market_tests/
│ └── a_share/
│ └── test_pipeline.py
├── docs/
│ └── modularization-development-plan.md
├── data/
│ ├── tushare/
│ ├── crypto/
│ └── ifind/
├── results/
├── requirements.txt
├── Dockerfile
└── README.md
说明:
src/quantcore/放跨市场共享的路径与 schema 工具src/quantbt/封装通用回测能力src/markets/a_share/是当前 A 股主模块src/markets/crypto/是当前 crypto 主模块src/markets/futures/目前是期货模块骨架,预留给后续接入src/quanta_stock/与src/quantcrypto/目前只保留兼容入口,便于平滑迁移src/markets/a_share/cli/提供当前 A 股模块入口src/markets/a_share/research/放研究逻辑,src/markets/a_share/providers/放数据源逻辑tests/market_tests/a_share/test_pipeline.py当前覆盖新的 A 股模块主路径data/crypto/是 crypto 研究数据目录,和 A 股data/tushare/分开data/ifind/是已有的人工导出 Excel 数据,不参与当前主回测流程
已完成的 TuShare 数据抓取包括:
- 全市场日线行情
daily - 全市场日度基本面
daily_basic - HS300 最新成分快照
hs300_constituents_latest - HS300 复权因子
adj_factor - HS300 涨跌停价格
stk_limit - HS300 动态成分与权重
index_weight - HS300 停复牌信息
suspend_d - A 股上市/退市/暂停上市基础信息
stock_basic - HS300 指数基准行情
index_daily
当前未成功落地的唯一一项是:
stock_st- 脚本已实现
- 当前 TuShare 账号无接口权限
- 因此仓库里只有一个空的占位 parquet
已完成两类研究面板:
- 基础面板:行情 +
daily_basic - 完整面板:在基础面板上补齐
adj_factor- 完整
qfq_*/hfq_*价格列 is_suspendedlist_status/list_date/delist_dateis_listed_from_stock_basicis_paused_listingis_stlimit_up/limit_downis_limit_up/is_limit_downis_one_word_limit_up/is_one_word_limit_downlisted_daysis_new_listing_60dret_1d/ret_5d/ret_20dvolatility_20damount_ma20_ratioturnover_rate_ma20_ratiois_tradeable_buy/is_tradeable_sell
当前仓库已经有完整的脚本闭环:
backtest_ma.py- 支持
--price-col - 默认使用
qfq_close - 可以直接用
close或qfq_close - 周 / 月调仓现在会在调仓日之间保持仓位
- 会读取
is_tradeable_buy/is_tradeable_sell - 输出净值、收益、持仓、指标和图表
- 支持
factor_test.py- 支持横截面因子分组
- 支持
daily / weekly / monthly调仓 - 默认使用
qfq_close - 分组时会过滤不可买入样本
- 输出分组净值、Long-short 指标、IC 序列和图
data_quality_check.py- 输出覆盖度、历史长度、缺失率和最新成分缺口检查
当前自动化测试已经覆盖以下 CLI 主路径:
build_panel.pybacktest_ma.pyfactor_test.pydata_quality_check.py
测试文件:
tests/market_tests/a_share/test_pipeline.py
主链路数据集中在 data/tushare/。
当前已实际落盘的核心 parquet:
daily_20150101_20241231.parquet- 全市场 A 股日线行情
- 约
948万行
daily_basic_20150101_20241231.parquet- 全市场日度估值、股本、流动性指标
- 约
936万行
adj_factor_hs300_20150101_20241231.parquet- HS300 复权因子
- 约
64万行
hs300_constituents_latest.parquet- HS300 最新成分快照
300行
stk_limit_hs300_20150101_20241231.parquet- HS300 涨跌停价格
639,983行
000300_sh_index_weight_20150101_20241231.parquet- HS300 动态成分与权重历史
51,000行
suspend_d_hs300_20150101_20241231.parquet- HS300 停复牌信息
11,858行
stock_basic_all_status.parquet- 上市 / 退市 / 暂停上市状态
5,818行
index_daily_000300_SH_20150101_20241231.parquet- 沪深300指数基准行情
2,431行
stock_st_20160101_20241231.parquet- ST 状态占位文件
- 当前为空
hs300_panel_20150101_20241231.parquet- 基础研究面板
628,796 x 23
hs300_panel_20150101_20241231_qfq.parquet- 基础面板 +
adj_factor+qfq_close 628,796 x 25
- 基础面板 +
hs300_panel_20241225_20241231.parquet- 小区间验证面板
1,495 x 23
hs300_panel_20150101_20241231_full.parquet- 当前最完整的研究面板
- 含完整前复权 / 后复权价格、动态成分过滤、停牌 / ST / 上市状态和交易可达性字段
- 频率:日频
- 时间范围:2015-01-01 到 2024-12-31
- 主键:
(ts_code, trade_date) - 默认股票池口径:动态 HS300 成分历史
- 默认研究价格列:
qfq_close
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt可选环境检查:
python scripts/env_check.pydocker build -t quant-dev .
docker run -it --rm --env-file .env -v $(pwd):/workspace -w /workspace quant-dev需要在项目根目录提供 .env:
TUSHARE_TOKEN=YOUR_TUSHARE_TOKEN或者在 config/config_tushare.py 中读取该环境变量。
当前 markets.a_share.providers.tushare 会优先读取环境变量 TUSHARE_TOKEN,config/config_tushare.py 仅作为回退。
当前推荐通过模块入口运行。示例命令基于 PowerShell:
$env:PYTHONPATH = (Resolve-Path .\src)当前推荐直接使用 markets.a_share.providers.tushare 中的 provider 函数组合拉取。
这部分 provider 已迁入模块,但下载型 CLI 还在继续补齐中。
输出:
data/tushare/raw/daily_20150101_20241231.parquetdata/tushare/raw/daily_basic_20150101_20241231.parquetdata/tushare/raw/hs300_constituents_latest.parquetdata/tushare/raw/adj_factor_hs300_20150101_20241231.parquet
当前推荐直接使用 markets.a_share.providers.tushare 中的 provider 函数组合拉取。
这部分 provider 已迁入模块,但下载型 CLI 还在继续补齐中。
输出:
data/tushare/raw/stk_limit_hs300_20150101_20241231.parquetdata/tushare/raw/000300_sh_index_weight_20150101_20241231.parquetdata/tushare/raw/suspend_d_hs300_20150101_20241231.parquetdata/tushare/raw/stock_basic_all_status.parquetdata/tushare/raw/index_daily_000300_SH_20150101_20241231.parquetresults/a_stock/panels/hs300_panel_20150101_20241231_full.parquet
说明:
- 当前脚本内部会尝试抓取
stock_st - 如果账号无权限,会保留空的占位文件而不中断主流程
python -m markets.a_share.cli.build_panel常用参数:
python -m markets.a_share.cli.build_panel `
--daily-path data/tushare/raw/daily_20150101_20241231.parquet \
--basic-path data/tushare/raw/daily_basic_20150101_20241231.parquet \
--universe-path data/tushare/raw/hs300_constituents_latest.parquet \
--adj-factor-path data/tushare/raw/adj_factor_hs300_20150101_20241231.parquet \
--stk-limit-path data/tushare/raw/stk_limit_hs300_20150101_20241231.parquet \
--suspend-path data/tushare/raw/suspend_d_hs300_20150101_20241231.parquet \
--stock-basic-path data/tushare/raw/stock_basic_all_status.parquet \
--stock-st-path data/tushare/raw/stock_st_20160101_20241231.parquet \
--output-path data/tushare/processed/hs300_panel_20150101_20241231.parquet说明:
- 如果
data/tushare/processed/不可写,会自动回退到results/a_stock/panels/ build_panel.py当前已经支持输出完整qfq_*/hfq_*列,并会把suspend_d、stock_basic_all_status、stock_st折叠进is_tradeable_buy/is_tradeable_sell- 当前口径下:停牌与暂停上市会同时禁止买卖,ST 仅禁止买入,涨跌停分别禁止对应方向成交
默认使用 full 面板和 qfq_close:
python -m markets.a_share.cli.backtest_ma如果想显式指定:
python -m markets.a_share.cli.backtest_ma --panel-path results/a_stock/panels/hs300_panel_20150101_20241231_full.parquet --price-col qfq_close输出目录默认在 results/a_stock/backtests/ma_strategy/,包括:
ma_backtest_nav.csvma_backtest_returns.csvma_backtest_positions.csvma_backtest_metrics.jsonma_backtest_summary.csv
python -m markets.a_share.cli.factor_test --factor pe_ttm示例:
python -m markets.a_share.cli.factor_test `
--panel-path results/a_stock/panels/hs300_panel_20150101_20241231_full.parquet \
--factor pe_ttm \
--groups 5 \
--rebalance monthly输出目录默认在 results/a_stock/factor/。
python -m markets.a_share.cli.data_quality_check --save-csv输出目录默认在 results/a_stock/data_quality/。
src/quantbt/ 是当前仓库的回测核心。
提供:
BacktestEngineSignalGeneratorPositionBuilderReturnCalculatorMASignalGeneratorMomentumSignalGeneratorMeanReversionSignalGenerator
当前回测引擎的关键设计是:
- 信号生成后显式
shift(1)执行,避免未来函数 weekly / monthly调仓频率会在调仓日之间保持上次仓位- 会读取
is_tradeable_buy/is_tradeable_sell约束真实可执行仓位 - 支持简单成本模型
- 可接入 benchmark 计算 Alpha / Beta / Information Ratio
提供基础绩效指标:
- 总收益
- 年化收益
- 波动率
- 最大回撤
- Sharpe
- Sortino
- Calmar
- 胜率
- 盈亏比
- Alpha / Beta
- Information Ratio
提供手续费、印花税、滑点和换手估算。
提供结果导出和图表绘制。
src/markets/a_share/ 是当前 A 股研究主模块,负责把 A 股数据链路从脚本层抽出来,形成独立封装。旧的 src/quanta_stock/ 目前仅保留兼容入口。
当前结构:
paths.py- 定义
data/tushare/、results/a_stock/等 A 股专属路径
- 定义
data/- 封装面板构建、动态成分过滤、复权、涨跌停、停牌 / ST / 上市状态过滤
cli/- 当前 A 股模块入口,包含
build_panel、backtest_ma、factor_test、data_quality_check
- 当前 A 股模块入口,包含
research/- 放研究逻辑,当前已拆出
factor.py和quality.py
- 放研究逻辑,当前已拆出
providers/- 放数据源逻辑,当前已拆出
tushare.py
- 放数据源逻辑,当前已拆出
当前职责边界:
src/markets/a_share/cli/*- A 股 CLI 入口
src/markets/a_share/research/*- A 股研究逻辑
src/markets/a_share/providers/*- A 股数据源逻辑
src/markets/a_share/*- A 股数据与研究准备逻辑
src/quantbt/*- 通用回测 / 指标 / 成本模型
src/markets/crypto/ 是当前仓库中的 crypto 主模块,用于把数字资产数据采集与 A 股研究链路彻底分开。旧的 src/quantcrypto/ 目前仅保留兼容入口。
当前结构:
paths.py- 定义
data/crypto/raw/目录
- 定义
providers/okx.py- 提供 OKX REST K 线抓取与 CSV 保存
providers/yahoo.py- 提供 Yahoo Finance OHLCV 下载与字段归一
对应 CLI:
- 当前 crypto CLI 仍在规划中
- 当前主要通过 provider 模块直接使用
示例:
python -c "from markets.crypto import fetch_okx_candles; print(fetch_okx_candles(inst_id='BTC-USDT', bar='1D', limit=5).head())"默认输出目录:
data/crypto/raw/
stock_st空占位文件- 交易过滤已接入停牌 / 上市状态 / ST,但仍是研究级约束,不包含更细的撮合与成交量冲击
- crypto 子模块目前只覆盖数据抓取与规范化,还没有形成独立回测链路
- A 股与 crypto 现在已经在目录、数据路径、封装层上拆开
- 给因子测试增加行业中性化、可交易过滤和基准对比
- 将
data_quality_check.py扩展为专门输出停牌 / ST / 暂停上市覆盖率 - 让回测引擎的
cost_model真正参与扣费,而不是只保留接口层 - 为
markets.crypto增加独立的回测 / 因子研究链路,而不是只停留在行情抓取
运行主测试:
python -m unittest discover -s tests -v当前这组测试主要验证:
- 面板构建是否成功
- MA 回测 CLI 是否产出结果
- 因子分组回测 CLI 是否产出指标和图
- 数据质量检查 CLI 是否成功输出 CSV
- 所有真实数据默认都在
data/和results/下,本地生成,不入 Git - README 里的数据规模和文件名反映的是当前仓库实际状态,不是预期状态