# AlphaGPT · 横截面因子挖掘版

> 基于开源项目 [AlphaGPT](https://github.com/imbue-bit/AlphaGPT) 改造。
> 原版面向 Solana meme 币，本版改造为**通用横截面因子挖掘系统**。
> 用 Transformer 自动生成因子公式，回测打分驱动强化学习，挖掘可解释的横截面选股因子。

---

## 这是什么

一句话：**它不预测涨跌，而是自动"写因子公式"。**

用一个 Transformer 当"公式生成器"，让它自动生成成千上万条因子公式（如 `SUB(close,open)`、`CORR20(close,volume)`），用横截面回测打分作为奖励，通过强化学习让生成器越写越好。最终产出一批**在样本外也站得住**的因子。

- **输入**：你自己的数据（pandas DataFrame，含 `date` / `instrument` + 任意特征列）——A股、期货、加密货币，任意品种，任意频率
- **输出**：因子公式 + 每个标的每个时间点的因子值 + 因子池排行榜
- **特点**：不挑品种不挑频率、GPU 加速、自带样本外验证防过拟合、算子白盒可查

---

## 效果示例

![因子净值曲线](factor_nav.png)

`demo.ipynb` 用 16 个期货主力合约（2020~2023，约745个交易日）跑出的一条因子——同一套引擎换成 A 股或加密货币数据，用法完全一样：

```
ABS(MAX3(ABS(CORR20(MAX3(MAX3(CORR20(MAX3(SIGN(settle)),close))),open_interest))))
```

按该因子值排序，每天买入头部 10%（多头组）/ 尾部 10%（空头组），与全市场等权基准对比净值，
该公式训练集 IR = 1.43，测试集（样本外）IR ≈ 1.25。

> ⚠️ 这只是一次演示，不是效果承诺：标的数少（16个）、测试窗口短（约149天），单次高 IR
> 很可能是运气或轻度过拟合（详见下方"重要提醒"）。真实研究请换成你自己的全市场数据、
> 多年样本，多跑几次看测试集 IR 是否稳定，而不是只看这一张图。

---

## 快速开始

### 1. 环境

```bash
# Python 3.10+，推荐 3.11 / 3.13
pip install torch pandas numpy loguru tqdm scipy
```

GPU 可选但强烈推荐。装 CUDA 版 torch（以 CUDA 12.6 为例）：
```bash
pip install torch --index-url https://download.pytorch.org/whl/cu126
```
验证：`python -c "import torch; print(torch.cuda.is_available())"` 输出 `True` 即可。

### 2. 挖因子（三行）

```python
import pandas as pd
from equity_adapter.run_equity import mine_alpha

# df 是你的数据:长表,必须有 date、instrument 两列,其余特征列随意
# instrument 不挑品种(股票/期货/加密货币都行),date 不挑频率(日线/分钟线都行)
df = pd.read_parquet("你的数据.parquet")   # 或用你自己的取数接口

result = mine_alpha(
    df,
    feature_cols=['open', 'high', 'low', 'close', 'volume', 'amount', 'turn'],
    price_col='close',
    adjust_col='adjust_factor',   # 复权因子列,没有传 None
    top_k=0.2,                    # 每日买因子值最高的 20%
    train_ratio=0.8,             # 前80%训练,后20%样本外验证
    eval_every=10,               # 每10步在测试集监控一次
    pool_size=50,                # 保留 Top50 因子池
)
print(result['formula_str'])      # 最优因子公式
print(result['train_score'], result['test_score'])   # 训练集/测试集 IR
```

### 3. 用因子（拿公式加工成因子表）

```python
from equity_adapter.apply_factor import make_factor

factor_df = make_factor(df, result['formula_str'], adjust_col='adjust_factor')
# 返回长表: [date, instrument, factor],直接 pandas 加工

# 例:每天选因子值最高的 50 只
top = factor_df.sort_values('factor', ascending=False).groupby('date').head(50)
```

### 4. 跑一遍完整流程（挖掘 → 看池子 → 画净值 → 加工因子）

参考 [`demo.ipynb`](demo.ipynb)，按 Cell 顺序执行即可：取数 → `mine_alpha()` 挖掘 → 训练/测试 IR 判断过拟合 → 因子池转表格排序 → `plot_factor_nav()` 画净值曲线 → `make_factor()` 落地因子表。

---

## 数据格式

传入的 DataFrame 只有两个硬性要求：

| 列 | 说明 |
|----|------|
| `date` | 日期（规范的 datetime 或 `YYYY-MM-DD` 字符串） |
| `instrument` | 标的代码，股票/期货合约/交易对都行 |
| 其余列 | 任意特征（close/volume/turn/pe_ttm...），用哪些由 `feature_cols` 指定 |

- **不挑品种**：`instrument` 只是个标识符，框架不关心它是股票还是合约，`demo.ipynb` 里跑的就是期货主力合约。
- **不挑频率**：日线、分钟线、Tick 聚合线都能喂，`date` 列只是时间轴的排序键。
- **不用预先排序**：内部自动按时间/标的重排。
- **缺失特征列自动跳过**：`feature_cols` 里写了不存在的列会被忽略并提示，不报错。
- **注意**：同一天同一只标的别有重复行（会静默取最后一条）；这一点内部不报错，建议取数后自查。

---

## 核心特性

| 特性 | 说明 |
|------|------|
| 🎯 **横截面选股** | 每期全市场按因子排序，买 TopK，不挑品种不挑频率 |
| 🛡️ **样本外验证** | 前80%训练、后20%考试，自动诊断过拟合，防"背答案" |
| 📊 **因子池** | 不只给最优因子，保留 TopN 排行，每条含训练/测试 IR |
| 👁️ **过程监控** | 训练中实时显示训练/测试 IR 缺口，一眼看出过拟合趋势 |
| ⚡ **GPU 向量化** | 回测全向量化，全市场 5000+ 只每步约 1 秒 |
| 🔍 **算子白盒** | 13 个算子，另有纯 pandas 实现逐行对照（CORR 系列口径暂不一致，见下文） |
| 🔄 **复权处理** | 自动用复权因子算收益，避免除权日假跳空 |
| 🗄️ **因子转 SQL** | 公式一键转 DuckDB SQL，直接对接数据库入库 |

---

## 算子一览

所有算子定义在 `model_core/ops.py`（唯一源头，白盒可查）。当前挖掘词表共 **13 个算子**：

| 类型 | 算子 |
|------|------|
| 基础 | `ADD` `SUB` `MUL` `DIV` `NEG` `ABS` `SIGN` |
| 条件 | `GATE`（condition>0 选 x 否则 y） |
| 时序 | `DELAY1`（滞后1天）`DECAY`（衰减叠加）`MAX3`（近3日最大） |
| 相关 | `CORR5` `CORR20`（滚动秩相关/Spearman，量价配合因子） |

> **已停用**：`JUMP` 因**含未来函数**被移除：其 zscore 用整段时间(而非滚动窗口)
> 的均值/标准差，等于用还没发生的数据定义"什么算异常"。`CORR30/CORR60/CORR100` 因窗口
> 太长、在标的数少或测试集时间跨度短时容易退化成 NaN/常数而移出挖掘词表。加工层仍能
> 解析含它们的历史老公式（向后兼容），但这些算子产出的历史因子值本身有偏差，新研究不要依赖它。

**因子有两套实现**：
- `apply_factor.make_factor`（torch 版，快，训练用）
- `pandas_factor.make_factor_pd`（纯 pandas 版，白盒，研究核对用）

⚠️ **已知口径差异**：`CORR5`/`CORR20` 在 torch 版（`model_core/ops.py`）用的是
**Spearman 秩相关**，而 `pandas_ops.py` 当前实现是 `rolling().corr()`，即 **Pearson**。
两套实现在这两个算子上数值不对齐，"白盒互相校验"这条目前只对纯算术/时序类算子（ADD/SUB/
DELAY1/DECAY/MAX3 等）成立，含 CORR 的公式请以 torch 版结果为准，pandas 版仅供逻辑参考。

```python
# 白盒版:完全不依赖 torch,逻辑逐行可读
from equity_adapter.pandas_factor import make_factor_pd
factor_df = make_factor_pd(df, "CORR20(close,volume)", adjust_col='adjust_factor')
```

---

## 因子转 SQL（入库用）

挖到的因子公式可以**自动转成 DuckDB SQL**，直接对接你自己的数据库因子入库流程，
无需手写窗口函数。

```python
from equity_adapter.factor_to_sql import formula_to_sql

sql = formula_to_sql(
    "NEG(MAX3(CORR60(DELAY1(close), amount)))",
    src="{SRC}",     # 源表名占位符,套入入库流程时替换成你的表名/子查询
)
print(sql)           # 完整 SQL,最终输出 date, instrument, factor 三列
```

命令行也行：
```bash
python -m equity_adapter.factor_to_sql "你的因子公式" 你的源表名
```

**智能内联**：纯算术算子（ADD/ABS/MUL…）内联成表达式，时序算子（DELAY/DECAY/CORR/MAX3…）
各开一层 CTE，生成的 SQL 简洁可读。CORR 的"窗口不足置 NULL"等边界已自动处理。
非算术类算子（DELAY1/DECAY/MAX3 等）生成的 SQL 与 `pandas_ops.py` 结果逐行一致；
但 SQL 里的 `corr()` 是 Pearson，和挖掘端 torch 版的 Spearman 口径不同（见上文
CORR 算子说明），转换含 CORR 的公式入库前请留意这个差异。

---

## 项目结构

```
equity_adapter/            ★ 横截面因子挖掘核心模块(命名沿用最初的A股场景，实际不挑品种)
├── df_loader.py           DataFrame → 张量适配器(复权/标准化/停牌mask)
├── cs_backtest.py         横截面 TopK 超额回测(GPU向量化)
├── equity_vocab.py        动态因子词表(随特征列数自适应)
├── run_equity.py          挖掘入口 mine_alpha
├── apply_factor.py        因子加工 make_factor(torch版)
├── pandas_ops.py          算子的纯pandas实现(白盒)
├── pandas_factor.py       make_factor_pd(纯pandas版)
└── factor_to_sql.py       因子公式 → DuckDB SQL 转换器(入库用)

model_core/                模型与算子(资产无关)
├── ops.py                 算子唯一定义源(含 CORR 相关系数)
├── vm.py                  公式执行栈式虚拟机
├── vocab.py               词表定义
└── alphagpt.py 等          Transformer 生成器等原框架核心

demo.ipynb                 挖掘+加工+可视化全流程 demo(唯一入口)
custom_factor.py           单因子的纯 pandas 白盒实现示例
```

---

## 关键参数（mine_alpha）

| 参数 | 默认 | 说明 |
|------|------|------|
| `feature_cols` | 必填 | 用哪些列挖因子 |
| `price_col` | `'close'` | 算收益的价格列 |
| `adjust_col` | `None` | 复权因子列，None=不复权 |
| `top_k` | `0.2` | 每日买入比例 |
| `cost_rate` | `0.0015` | 单边换手成本 |
| `train_ratio` | `0.8` | 训练集时间占比 |
| `eval_every` | 自动 | 每几步监控测试集，0=关闭 |
| `pool_size` | `50` | 因子池保留 TopN |
| `steps` | `300` | 训练步数（正式研究建议 300~1000） |

---

## 输出文件

`mine_alpha()` 直接落盘两个文件（路径由 `save_path`/`pool_path` 参数指定）：

| 文件 | 内容 | 格式 |
|------|------|------|
| `best_equity_factor.json` | 最优因子公式 + 训练/测试 IR + 训练过程 history + 因子池 | JSON |
| `factor_pool.json` | 因子池排行（公式/token序列/训练IR/测试IR） | JSON |

其余产出是 `demo.ipynb` 里手动导出的，非框架自动生成：
- `因子池排行.csv` —— 因子池转表格后 `to_csv` 导出，方便 Excel 查看
- `factor_nav.png` —— `visualize.plot_factor_nav()` 画的净值曲线图

---

## 重要提醒

1. **样本外为准**：只看训练集 IR 会骗人。判断因子好坏，**以测试集 IR 为准**，且要接近训练集才算稳健。
2. **别过度解读单次结果**：单年、少标的的高 IR 大概率是过拟合。真研究要用多年 + 全市场 + 上千步，多跑几次挑测试集稳定的。
3. **这不是交易建议**：本项目是**因子研究工具**，不是自动交易系统。挖出的因子需经严格回测、风控、成本核算后才能考虑实盘。
4. **本版已移除原 meme 币的实盘/数据/看板模块**，专注因子研究。如需加密货币实盘功能，请参考[原项目](https://github.com/imbue-bit/AlphaGPT)。

---

## 致谢与许可

- 原项目：[AlphaGPT](https://github.com/imbue-bit/AlphaGPT)（见 [`README_original.md`](README_original.md)）
- 许可证：见 [`LICENSE`](LICENSE)（Apache 2.0）

本改造版在原框架基础上，重写了数据层、回测层，新增样本外验证、因子池、相关系数算子、pandas 白盒实现，把资产范围从加密货币扩展为通用横截面标的（A股/期货/加密货币均可）。
