Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

A 股多因子研究库

面向 LightGBM 训练、回测、模拟盘交易的 A 股多因子实现。10 大类、96 个因子,
每个因子都带公式、方向和证据等级。

架构说明见 docs/ARCHITECTURE.md —— 包含与华泰研报原文的
差异核对、关键设计决策、以及开发中实际发现并修掉的问题清单。


⚙️ 首次使用:环境搭建

需要 Python 3.10+(代码使用 X | None 等现代注解语法,

且 FastAPI 会主动解析路由签名,from __future__ import annotations 无法绕过)。

完整步骤见 docs/SETUP.md。速览:

py -3.12 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt

cd showcase\frontend
npm install

Python 依赖只有四个:fastapi / uvicorn[standard] / pandas / numpy。

不需要 sqlalchemy、pyarrow、matplotlib、scipy、scikit-learn、lightgbm ——

requirements.txt 里逐条写明了不引入的原因。


🌐 浏览器教学站(推荐从这里开始)

python run_showcase.py

然后打开 http://localhost:3000 —— 一条命令拉起 FastAPI 后端 + Next.js 前端。

每个因子都有自己的页面,展示六段内容:

段落 内容
① 它在算什么 通俗解释这个因子在问什么问题
② 公式与所需数据 公式、方向、证据等级、需要哪些数据字段
③ 真实输入 因子函数实际读到的数据表
④ 计算过程 逐步展示:原始值 → 去极值 → Z-score → 填 0 → 方向翻转
⑤ 源码 从定义文件读取的真正运行的那段代码
⑥ 为什么这样写 证据来源与易错点

页面上每个数字都由后端真实计算产出,不是前端写死的示例。

手写的示例数字会在代码变更时悄悄脱节 —— 这个项目里凡是能推导的一律推导。

例如 EP 页能看到 424 个 NaN、从 2015-01-01 一路 NaN 到 2016-03 才出值 ——

暖机期是可见的,而不是被 dropna 藏起来。

页面 说明
/ 总览:10 大类、证据等级分布
/factors 96 个因子,可按大类/证据等级筛选
/concepts 核心概念:面板方向、safe_div、处理链顺序……
/docs 原有 Markdown 文档(含 10 篇 ADR)已按标题拆节,可在浏览器翻阅

技术栈:Next.js 15 (App Router) + FastAPI + SQLite。

因子定义以 REGISTRY 为唯一事实来源,SQLite 只存讲解层,与量化库解耦。

⚠️ 回测、LightGBM 训练、实盘已按需求解耦,不在展示范围内。


📖 文档入口

不要从头读代码。 按目的选入口 —— 完整地图见 docs/READING_MAP.md。

我想… 看这个
快速搞懂这个库在干什么 检视指南 §1(五个核心概念)
看架构图 / 时序图 / 类图 架构图(9 张 Mermaid 图)
学 pandas / 搞清变量长什么样 pandas 速成(含真实输出)
查某个因子的定义和公式 因子速查表
知道为什么这样设计 ADR 决策记录(11 条)
知道现状离目标多远 差距分析
接自己的数据 数据契约

⚠️ 接真实数据之前请先读 GAP_ANALYSIS.md 的 P1#1:

财报 PIT 对齐在 disclosure 缺失时会回退用报告期,实测泄漏 29 天未来信息。

用 python tests/test_pit_leakage.py 可复现(当前 3/4 失败,是已知缺陷)。


快速开始

# 端到端自检(35 项,不需要 LightGBM)
python scripts/smoke_test.py

# 生成因子清单(CSV + Markdown)
python scripts/report_factors.py
from quant.data import make_synthetic_panel
from quant.factors import REGISTRY
from quant.pipeline import FactorPipeline
from quant.datasets import build_dataset
from quant.models import train_model

panel = make_synthetic_panel()                       # 真实数据见下
specs = REGISTRY.select(categories=["valuation", "growth", "quality"],
                        min_confidence="strong_infer")
run   = FactorPipeline().run(panel, specs)           # 算因子
ds    = build_dataset(run, panel, horizon_days=21)   # 建数据集
model = train_model(ds)                              # 训练 LightGBM

目录结构

quant/
├── config.py     处理口径、股票池、数据源配置
├── ops/          算子层:去极值/标准化/中性化 + 时序算子 + PIT 对齐
├── factors/
│   ├── registry.py   FactorSpec / REGISTRY —— 因子库的唯一事实来源
│   └── defs/         10 个大类的因子定义
├── data/         Panel 组装、PIT 对齐、parquet 缓存、合成数据
├── pipeline/     因子计算引擎
├── datasets/     数据集构建(标签、掩码、防未来函数、切分)
├── models/       LightGBM 训练与 IC 评估
├── backtest/     组合回测 + 单因子 IC 检验
└── live/         模拟盘/实盘循环、下单、Broker 接口

因子一览

大类 数量 代表因子
valuation 估值 16 EP BP SP OCFP PEG EV2EBITDA
turnover 换手率 13 turn_1m/3m/6m bias_turn_* std_turn_*
quality 财务质量 12 ROE ROA GrossMargin Accrual AssetTurn
growth 成长 12 Sales_G_{q,ttm,3y} Profit_G_* OCF_G_* ROE_G_*
technical 技术 12 MACD(10/30/15) DIF DEA PVCorr_* Alpha3/13/15/16/44/50/55
volatility 波动率 10 std_4m id1_std_3m id2_std_* high_r_std_4m Beta
momentum_modified 改进动量 8 wgt_return_* exp_wgt_return_*
leverage 杠杆 5 DebtToAssets FinLeverage DebtToEquity CashRatio
momentum 动量 5 Return_1m/3m/6m/12m HAlpha
size 规模 3 LnMktcap

每个因子带 confidence 等级(研报确证 / 强推断 / 社区推断 / 存疑)。
按证据强度筛选:

REGISTRY.select(min_confidence="confirmed")        # 只要原文逐字确证的
REGISTRY.select(categories=["momentum"], live_safe_only=True)
REGISTRY.manifest()                                # 导出完整清单

完整清单见 reports/factor_inventory.csv。


接真实数据

因子层只认 Panel,不认任何厂商 API。两种接入方式:

A. 导出 parquet(推荐,之后研究全离线可复现)

data/raw/close.parquet              # date x asset,后复权
data/raw/turnover.parquet
data/raw/mktcap_total.parquet
data/raw/fundamentals/ocf_ttm.parquet
data/raw/disclosure.parquet         # 报告期 x asset 的披露日期
data/raw/benchmark.parquet

所需字段不必猜 —— 从因子声明反推:

specs = REGISTRY.select(categories=["growth"])
print(REGISTRY.required_fundamentals(specs))

B. 实现 DataLoader,接 Wind / Tushare / 自建数仓:

from quant.data import DataLoader, DataRequest

class MyLoader(DataLoader):
    def load_raw(self, req): ...
    def load_fundamentals(self, req): ...

处理口径(华泰原文)

固定顺序,写在 config.ProcessingConfig:

去极值(MAD, k=5,不乘 1.4826) → Z-score → 缺失值填 0

三个易错点已在代码中显式化并注释:

  • MAD 不乘 1.4826(乘了阈值放宽约 48%)
  • 缺失值在标准化之后填 0
  • 市值中性化只在算 IC 时做,回归法只加行业哑变量

依赖

必需:numpy、pandas(仅此二者即可完成因子计算、数据集构建、回测)。

可选:lightgbm(惰性导入,训练时才需要)

python -m pip install lightgbm -i https://pypi.tuna.tsinghua.edu.cn/simple

刻意不依赖 scipy:RankIC 用 numpy 的「秩上 Pearson」实现,避免核心指标受可选包影响。


已知待确认项

见 docs/ARCHITECTURE.md §7,要点:
原清单「72」与图片小计 70 差 2 的来源;创业板/科创板涨跌停幅度需按板块配置;
杠杆类 5 个中 4 个无研报原文确证。

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages