Skip to content

An Automatic Quantitative Factor Miner using Multi-Agent System.

Notifications You must be signed in to change notification settings

CUFEL-X/7-MASFactorMiner

Repository files navigation

第 7 练 MAS-FactorMiner

一、练习说明

背景

在第 7 练中,我们将基于 MAS 来解决量化投资场景中的常见问题——因子挖掘。

在量化投资领域,因子可以简单理解为一种对资产价格有预测能力的时序特征,因子的数量与质量则是量化投资的核心竞争力之一。

随着量化投资进入“拥挤时代”,有效的量化投资策略对于因子数量和质量提出了更高的要求。传统的人工挖掘因子的速度较慢、成本较高,遗传规划(Genetic Programming)算法虽能生成海量因子,却面临“公式黑箱”与“可解释性差”的难题。如何利用大语言模型(LLM)对金融语义和经济逻辑的理解能力,构建可解释、高效率的因子挖掘流水线,成为行业前沿的探索方向。

题目描述

  • 设计项目实现的方案, 并利用 Vibe Coding 完成项目构建。
  • 因子挖掘流水线设计,包括但不限于:算子池设计、因子生成、因子计算、因子评价、因子优化。
  • 输出内容设计,包括但不限于:中间过程报告、总结报告、可视化因子分析

二、题目解析

多智能体量价因子挖掘系统 (Multi-Agent System for Factor Mining)

基于大语言模型的自动化量化因子挖掘框架,通过四个协作 Agent 实现因子的自动生成、计算、评估和优化闭环。并通过 tools 功能提高 Agent 表现。


目录


系统架构

Agent 名称 职责 其他说明
Agent 1 因子构想家 (Ideator) 基于金融逻辑生成因子表达式 支持使用 Tools 功能增强 Agent 即刻验证的能力
Agent 2 因子计算师 (Calculator) 解析表达式、计算因子值、修复错误 修复失败表达式时使用 LLM 进行修复
Agent 3 因子评估师 (Evaluator) 计算 IC/ICIR 等指标、生成分析报告 由 Agent 撰写评估分析报告
Agent 4 因子优化家 (Optimizer) 基于评估反馈优化因子 支持使用 Tools 功能增强 Agent 即刻验证的能力

挖掘流程

整体流程

初始化 → 加载数据 → [生成基础因子池] → [迭代挖掘 × N轮] → 生成最终报告 → 生成可视化图表 → 保存最终结果

单轮迭代

Step 1: 因子构想 (Agent1)
  │  输入: 因子数量、历史因子列表、优化反馈、数据描述、可用字段
  │  任务: 生成新的因子表达式,支持 text/tool/function_call 三种模式
  │  输出: 因子列表(名称、表达式、逻辑)
  v
Step 2: 因子计算 (Agent2)
  │  输入: 因子表达式列表
  │  任务: 批量计算因子值,失败时 LLM 修复表达式
  │  输出: 计算结果(成功/失败、因子值、错误信息)
  v
Step 3: 因子评估 (Agent3)
  │  输入: 计算成功的因子结果
  │  任务: 计算 IC/ICIR 等指标,生成综合评分和分析报告
  │  输出: 评估结果(评分、有效性、方向、指标)
  v
Step 4: 更新最佳因子
  │  任务: 维护最佳因子列表,按评分排序
  │  输出: 更新后的最佳因子列表
  v
Step 5: 保存迭代结果
  │  任务: 保存每轮数据和报告
  │  输出: iteration_{i}.json 和 report_iteration_{i}.md
  v
Step 6: 因子优化 (Agent4,非最后一轮)
  │  输入: 评估结果、分析报告、因子数量
  │  任务: 生成优化因子和反馈,支持变异/交叉/精炼策略
  │  输出: 优化因子列表和反馈信息,传递给下一轮
  v
进入下一轮

Step 1 - 因子构想:FactorIdeator Agent 使用 LLM 生成因子表达式。第1轮基于数据描述探索性生成,后续轮基于优化反馈改进。支持三种模式:text(文本解析)、function_call(结构化输出)、tool(工具增强,可即时验证)。

Step 2 - 因子计算:FactorCalculator 解析并计算因子表达式,支持基础因子引用展开。计算失败时自动调用 LLM 修复。

Step 3 - 因子评估:FactorEvaluator 计算多周期 IC/ICIR、分层回测等指标,生成综合评分(0-100,加权 IC/ICIR/单调性/胜率)。使用 LLM 生成分析报告。

Step 4 - 更新最佳因子:将评估结果与现有最佳因子比较,更新列表,按评分排序。

Step 5 - 保存迭代结果:保存每轮详细数据到 JSON 文件,分析报告到 Markdown 文件。

Step 6 - 因子优化:FactorOptimizer Agent 使用 LLM 基于评估反馈优化因子,通过变异、交叉、精炼生成新因子,并提供反馈给下一轮构想。


三种生成模式

系统支持三种 LLM 生成模式,通过 config.yaml 中的 generation_mode 切换:

文本解析模式

generation_mode: "text"
  • LLM 自由返回文本,程序通过正则/JSON 解析提取因子
  • 兼容性最好,适用于所有 LLM
  • 解析可靠性依赖 LLM 的格式遵从度

结构化输出模式

generation_mode: "function_call"
  • 使用 LangChain with_structured_output() + Pydantic Schema
  • LLM 直接返回结构化数据,无需文本解析
  • 每轮 1 次 API 调用,成本最低
  • 需要 LLM 支持 function calling

Tool 模式(工具增强,推荐)

generation_mode: "tool"
  • LLM 通过 Agentic Loop 迭代调用工具
  • 可调用 validate_and_compute_factor 验证表达式并查看统计量
  • 可调用 evaluate_factor_quick 快速评估 IC/ICIR
  • 闭环生成:构思 → 验证 → 评估 → 修正 → 确定
  • 该模式下因子生成质量较高,但是消耗的Toke也较多

三种模式对比:

特性 Text Structured Output Tool
交互方式 单轮文本 单轮结构化 多轮工具调用
因子质量 一般 一般 高(可自我验证)
API 调用 / 轮 1 1 多轮
兼容性 所有 LLM 需支持 FC 需支持 FC
回退机制 - → Text → FC → Text

Tool 模式工作流程

LLM 构思因子
    │
    ├── 调用 validate_and_compute_factor("div(sub(close, ts_mean(close,20)), ts_std(close,20))")
    │   └── 返回: {valid: true, stats: {coverage: 0.92, mean: 0.01, std: 1.23, ...}}
    │
    ├── 调用 evaluate_factor_quick(expression, "zscore_20d")
    │   └── 返回: {mean_ic: 0.035, icir: 0.42, quality: "good", ...}
    │
    ├── 保留该因子,构思下一个...
    │
    ├── 调用 validate_and_compute_factor("ts_return(close, -5)")
    │   └── 返回: {valid: false, error: "时间窗口必须为正整数"}
    │
    ├── 修正 → validate_and_compute_factor("ts_return(close, 5)")
    │   └── 返回: {valid: true, ...}
    │
    └── 最终输出所有通过验证的因子列表

基础因子池

系统支持预先生成一组"基础因子",供后续因子构建时作为积木引用。

配置

base_factors:
  enabled: true
  factors_per_category: 2
  categories:
    - momentum       # 动量类
    - reversal       # 反转类
    - volatility     # 波动率类
    - volume_price   # 量价背离类
    - trend          # 趋势类
    - liquidity      # 流动性类
  temperature: 0.5

引用语法

在因子表达式中使用 $因子名 引用基础因子:

# 基础因子: $momentum_5d = ts_return(close, 5)
# 基础因子: $volatility_20d = ts_std(close, 20)

# 复合因子:动量/波动率比
div($momentum_5d, $volatility_20d)

# 展开后等价于:
div(ts_return(close, 5), ts_std(close, 20))

基础因子由 BaseFactorGenerator 通过 LLM + Tool Calling 生成,存储在 BaseFactorRegistry 中。


因子算子

可用数据字段

字段 说明 示例用途
open 开盘价 缺口分析
high 最高价 压力位、振幅
low 最低价 支撑位、振幅
close 收盘价 动量、均线
vol 成交量 量能分析
amount 成交额 资金流向
pct_chg 涨跌幅 收益率分析

实际可用字段取决于 config.yaml 中的 data_fields 配置。

算子分类

一元运算符

算子 语法 说明
abs abs(x) 绝对值
sign sign(x) 符号函数
log log(x) 自然对数
neg neg(x) 取负
sqrt sqrt(x) 平方根

二元运算符

算子 语法 说明
add add(x, y) 加法
sub sub(x, y) 减法
mul mul(x, y) 乘法
div div(x, y) 除法
max max(x, y) 最大值
min min(x, y) 最小值
power power(x, n) 幂运算

时序运算符

算子 语法 说明
ts_mean ts_mean(x, d) d 日移动平均
ts_std ts_std(x, d) d 日移动标准差
ts_sum ts_sum(x, d) d 日移动求和
ts_max ts_max(x, d) d 日移动最大值
ts_min ts_min(x, d) d 日移动最小值
ts_delta ts_delta(x, d) d 日差分 (x - x_d天前)
ts_delay ts_delay(x, d) d 日延迟 (x_d天前)
ts_return ts_return(x, d) d 日收益率
ts_corr ts_corr(x, y, d) d 日滚动相关系数

因子表达式示例

# 布林带位置 (Z-Score)
div(sub(close, ts_mean(close, 20)), ts_std(close, 20))

# 量价同步变化
mul(ts_delta(close, 1), ts_delta(vol, 1))

# 标准化动量
div(ts_delta(close, 5), ts_std(close, 10))

# 量价相关性
ts_corr(close, vol, 20)

# 使用基础因子的复合因子
div($momentum_5d, $volatility_20d)

评估指标

核心指标

指标 说明 有效阈值 优秀阈值
Mean IC 因子值与未来收益的 Spearman 相关系数均值 |IC| > 0.02 |IC| > 0.05
ICIR IC 均值 / IC 标准差,衡量 IC 稳定性 |ICIR| > 0.1 |ICIR| > 0.5
IC 胜率 IC 为正的交易日占比 > 55% > 65%
多空收益 最高组与最低组的收益差 > 0.5% > 1%

综合评分公式

评分 = IC得分(40%) + ICIR得分(30%) + 分层单调性得分(20%) + IC胜率得分(10%)

其中:
- IC得分 = min(|IC| / 0.05 * 40, 40)
- ICIR得分 = min(|ICIR| / 0.5 * 30, 30)
- 单调性得分 = min(|多空收益| / 0.01 * 20, 20)
- 胜率得分 = max(0, min((胜率 - 0.5) / 0.2 * 10, 10))

因子方向

  • 正向因子 (IC > 0):因子值越大,未来收益越高
  • 负向因子 (IC < 0):因子值越小,未来收益越高

系统自动识别因子方向,负向因子在使用时取反。


项目结构

MASFactorMiner/
├── run.py                       # 运行入口
├── config/
│   └── config.yaml              # 配置文件
├── src/
│   ├── __init__.py
│   ├── main.py                  # 主控编排 (FactorMiner)
│   │
│   │  # ── 四大 Agent ──
│   ├── agent_ideator.py         # Agent1: 因子构想家
│   ├── agent_calculator.py      # Agent2: 因子计算师
│   ├── agent_evaluator.py       # Agent3: 因子评估师
│   ├── agent_optimizer.py       # Agent4: 因子优化家
│   │
│   │  # ── 基础设施 ──
│   ├── llm_client.py            # LLM 客户端 (chat/FC/Tool Loop)
│   ├── operators.py             # 算子定义与实现
│   ├── data_loader.py           # 数据加载器
│   ├── schemas.py               # Pydantic 输出 Schema
│   ├── agent_tools.py           # Tool 模式工具定义
│   │
│   │  # ── 基础因子 ──
│   ├── base_factor_generator.py # 基础因子生成器
│   ├── base_factor_registry.py  # 基础因子注册表
│   ├── expression_utils.py      # 表达式展开/验证工具
│   │
│   │  # ── 可视化 ──
│   └── factor_visualizer.py     # 图表生成模块
│
├── results/                     # 输出结果目录
├── .env                         # LLM API 配置
├── pyproject.toml               # 项目依赖
└── README.md

核心模块说明

模块 文件 职责
LLM 客户端 llm_client.py 封装 LangChain ChatOpenAI,提供 chat()chat_with_structured_output()chat_with_tools_loop()
输出 Schema schemas.py 定义 FactorListOptimizedFactorListMutationResult 等 Pydantic 模型
Tool 定义 agent_tools.py 定义 validate_and_compute_factorevaluate_factor_quick 两个 LLM 可调用工具
算子引擎 operators.py 实现所有一元/二元/时序算子,支持 pandas DataFrame 运算
表达式工具 expression_utils.py 基础因子引用展开 ($name → 表达式)、算子计数、表达式验证

快速开始

1. 环境配置

# 使用 uv (推荐)
uv sync

# 或使用 pip
pip install -r requirements.txt

Python 版本要求: >= 3.11

核心依赖:

  • langchain / langchain-openai >= 1.0.0 (LLM 调用框架)
  • pandas / numpy / scipy (数值计算)
  • pydantic >= 2.0.0 (结构化输出 Schema)
  • matplotlib / seaborn (可视化)

2. 配置 LLM

创建 .env 文件:

LLM_API_KEY=your_api_key
LLM_URL_BASE=https://your-llm-server/v1
MODEL_NAME=your-model-name

兼容所有 OpenAI API 格式的模型服务(OpenAI、DeepSeek、Qwen 等)。

3. 准备数据

将日频量价数据 CSV 文件放入项目根目录,并在 config/config.yaml 中配置数据路径和字段映射。

4. 运行挖掘

# 使用默认配置
python run.py

# 指定配置文件
python run.py -c config/config.yaml

# 覆盖迭代参数
python run.py --max-iterations 5 --factors-per-round 10
参数 简写 说明 默认值
--config -c 配置文件路径 config/config.yaml
--max-iterations - 最大迭代轮数 配置文件中的值
--factors-per-round - 每轮生成因子数量 配置文件中的值

配置说明

配置文件位于 config/config.yaml

LLM 配置

llm:
  temperature: 0.7      # 生成温度 (0-1),越高越有创造性
  max_tokens: 16384     # 单次生成最大 token 数

API 密钥等敏感信息从 .env 文件读取:

  • LLM_API_KEY: API 密钥
  • LLM_URL_BASE: API 基础 URL
  • MODEL_NAME: 模型名称

数据配置

data:
  file_path: "etf_2025_data.csv"
  has_header: true
  code_column: "code"
  date_column: "date"
  adj_factor_column: "adj_factor"
  data_fields:
    - "open"
    - "high"
    - "low"
    - "close"
    - "vol"
    - "amount"
    - "pre_close"
    - "change"
    - "pct_chg"
    - "adj_factor"
  data_description: |
    该数据是ETF的日频交易数据...

data_description 会传递给 Agent1 的 LLM,描述越详细,生成的因子越合理。

因子挖掘配置

factor_mining:
  factors_per_round: 10        # 每轮生成因子数量
  max_iterations: 3            # 最大迭代轮数
  max_expression_depth: 9      # 表达式最大嵌套深度
  lookback_days: 60            # 时序计算回溯天数

  # LLM 交互模式: "text" / "function_call" / "tool"
  generation_mode: "function_call"

  # Tool 模式配置
  tool_mode:
    max_loop_iterations: 20    # Agentic Loop 最大迭代次数
    verbose: true              # 是否打印工具调用详情

  # 算子采样(增加因子多样性)
  operator_sampling:
    enabled: false
    sample_ratio: 0.7          # 每轮随机保留 70% 算子
    core_operators:            # 必须保留的核心算子
      - "add"
      - "sub"
      - "mul"
      - "div"
      - "ts_mean"
      - "ts_std"
      - "ts_return"
参数 说明 建议值
factors_per_round 每轮生成因子数量 5-15
max_iterations 迭代轮数 3-10
generation_mode LLM 交互模式 "function_call""tool"
operator_sampling.enabled 启用算子采样可增加多样性 true

因子评估配置

evaluation:
  ic_periods: [1, 2, 3, 5]    # IC 计算周期(天)
  main_period: 5               # 主评估周期
  ic_threshold: 0.02           # IC 绝对值阈值
  icir_threshold: 0.1          # ICIR 绝对值阈值
  consider_negative_ic: true   # 保留负 IC 因子(取反使用)
  quantile_groups: 8           # 分层回测组数

优化配置

optimization:
  strategies:
    - "mutation"      # 变异:微调参数或算子
    - "crossover"     # 交叉:组合多个因子
    - "refinement"    # 精炼:简化或增强表达式
  top_k_factors: 5    # 每轮保留的优秀因子数量

输出配置

output:
  results_dir: "results"
  generate_plots: true
  plot_period: 5
  save_intermediate: true

输出结果

每次运行在 results/ 下创建带时间戳的结果目录:

results/run_20260205_143052/
├── config.yaml                         # 本次运行的配置快照
├── data/
│   ├── iteration_1.json                # 第 1 轮迭代详细数据
│   ├── iteration_2.json
│   └── iteration_3.json
├── factors/
│   ├── all_factors.json                # 所有因子完整信息
│   ├── base_factors.json               # 基础因子池(若启用)
│   └── valid_factors_summary.csv       # 有效因子汇总表
├── reports/
│   ├── report_iteration_1.md           # 每轮分析报告
│   ├── report_iteration_2.md
│   ├── report_iteration_3.md
│   └── final_report.md                 # 最终汇总报告
└── plots/
    ├── final_factors_comparison.png     # 因子对比图
    ├── final_summary_dashboard.png      # 汇总仪表板
    └── final_{factor_name}_detail.png   # 单因子详图
图表 内容
factors_comparison.png 所有因子的评分、IC、ICIR、胜率对比
summary_dashboard.png 汇总仪表板:关键指标、分布、排行榜
{factor_name}_detail.png 单因子详图:累计 IC、IC 时序、IC 分布、分层收益

常见问题

1. 因子计算失败怎么办?

系统会自动使用 LLM 修复表达式。如仍失败,检查:

  • 表达式语法是否正确(括号匹配、算子存在)
  • 时间窗口参数是否为正整数
  • 数据字段名是否与 data_fields 配置一致

2. 有效因子数量少怎么办?

  • 切换到 generation_mode: "tool" 让 LLM 自我验证
  • 增加 factors_per_round 生成更多候选
  • 增加 max_iterations 迭代轮数
  • 降低 ic_thresholdicir_threshold
  • 启用 operator_sampling 增加多样性

3. API 调用成本过高怎么办?

  • 使用 generation_mode: "function_call""text"(每轮仅 1 次调用)
  • 减少 factors_per_round
  • 减少 max_iterations
  • 使用更便宜的模型

4. 支持哪些 LLM?

兼容所有 OpenAI API 格式的服务:

  • OpenAI (GPT-4, GPT-4o 等)
  • DeepSeek
  • Qwen (通义千问)
  • 其他兼容 OpenAI 格式的本地或云端模型

Function Call 和 Tool 模式需要模型支持 function calling 能力。


Team

金融人工智能北京市重点实验室

License

MIT License

About

An Automatic Quantitative Factor Miner using Multi-Agent System.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages