量化交易中的 Universe:股票池定义、过滤规则与数据获取

Universe 是什么

量化交易里,Universe(投资宇宙 / 股票池)指策略允许选股和交易的资产集合。简单理解:

Universe = 你的策略在哪些股票里选

比如:

  • 沪深 300 成分股(300 只)
  • 中证 500 成分股(500 只)
  • 全 A 股剔除 ST、停牌、次新股后的剩余标的
  • 某个行业的所有上市公司

为什么要定义 Universe

A 股有 5000+ 只股票。如果不做筛选,直接在全市场跑因子计算:

  • 计算量大,速度慢
  • 流动性差的股票出信号无法成交
  • 次新股、ST 股信号质量差,噪声多

先定义好 Universe,再在 Universe 里做因子计算、排名、选股,是量化策略的标准流程:

全市场(5000+只)
    ↓ Universe 过滤
符合条件的股票池(如 3000 只)
    ↓ 因子计算
每只股票打分
    ↓ 排序选股
前 N 名 → 下单交易

静态 Universe

直接用指数成分股,每次调仓时更新成分股列表:

import akshare as ak

# 沪深 300 成分股
df = ak.index_stock_cons_csindex(symbol="000300")
universe = df["成分券代码"].tolist()
# 中证 500
df = ak.index_stock_cons_csindex(symbol="000905")
universe = df["成分券代码"].tolist()

动态 Universe

每天收盘后重新计算,根据流动性、市值等条件动态生成:

import pandas as pd

def build_universe(daily_data: pd.DataFrame) -> list:
    """
    daily_data: 包含 code, close, volume, market_cap, is_st, list_days 等列
    """
    universe = daily_data[
        (~daily_data["is_st"]) &           # 剔除 ST
        (daily_data["list_days"] >= 60) &   # 上市满 60 天
        (daily_data["volume"] > 0) &        # 非停牌
        (daily_data["market_cap"] > 5e9) &  # 市值 > 50 亿
        (daily_data["turnover_20d"] > 5e7)  # 20 日均成交额 > 5000 万
    ]
    return universe["code"].tolist()

常用 Universe 类型

Universe说明适合策略
沪深 300 成分股蓝筹龙头,流动性好低换手率、稳健因子
中证 500 成分股中盘股,成长性较好中小盘因子
中证 1000 成分股小盘股,弹性大小盘动量、题材
全 A 剔除 ST/停牌覆盖面广全市场扫描
行业 Universe限定某一行业行业轮动、配对交易

在量化框架中使用

JoinQuant(聚宽):

from jqdata import get_index_stocks

universe = get_index_stocks("000300.XSHG")  # 沪深 300

Qlib:

# qlib 配置文件
market: csi300

vn.py / 自研框架:

universe = build_universe(daily_df)

for code in universe:
    factor_score = compute_factor(code)
    ...

Universe 与 AI Agent 量化

在 AI Agent 驱动的量化系统里,Universe 还有另一层含义:限定 Agent 的分析范围。

universe:
  - A股
  - 港股
  - ETF

配置好 Universe 后,Agent 的新闻抓取、因子计算、持仓分析都限制在这个范围内,避免无限制扩散导致计算量和 Token 消耗失控。