【AI+量化实战 #08】多因子打分的AI解释层:把因子得分变成选股理由
风险提示:本文仅用于技术演示,不构成投资建议。多因子得分只是研究辅助,不能替代独立判断。
你算出了一堆因子:动量、波动、资金流、估值……然后给每只股票打了个综合分。
老板问你:"这只股票为什么排第一?"
你支支吾吾:"因为它的 z-score 加权后比较高……"
这就是量化研究里最容易被忽视的环节:把数字翻译成可理解的投资语言。今天的文章教你用 AI 给多因子得分加一个"解释层",让每一只股票的排名都有理由、有边界、有风险提示。
本文你将得到什么
- 一个三因子(动量 + 波动 + 资金流)打分模型;
- 一段可直接运行的 Python 脚本,自动给股票排名并生成解释;
- 规则模板解释 + LLM 增强解释两种模式;
- 一个实用的 Prompt 模板,可直接接入你自己的大模型。
一、为什么需要解释层
多因子模型的输出通常是这样的:
| 股票 | 动量 | 波动 | 资金流 | 综合得分 |
|---|---|---|---|---|
| 000001 | 4.36% | 5.05% | -3.73 | 0.52 |
| 300750 | 10.08% | 10.49% | 4.88 | 0.42 |
| 002230 | 2.04% | 9.25% | -22.73 | -1.02 |
看得懂数字的人知道 0.52 比 -1.02 好,但好在哪里、为什么好、潜在风险是什么,光看分数不够直观。
解释层的作用就是把:
"score = 0.52"
变成:
"这只股票近 20 日涨幅 4.36%,波动仅 5.05%,在样本中波动控制最好;虽然大单动向偏弱,但综合仍属强势,需关注后续资金是否回流。"
二、三因子模型:动量、波动、资金流
我们选取三个最常见、也最容易获取的因子:
- 动量(Momentum):近 20 日涨幅,反映趋势强度;
- 波动(Volatility):近 20 日收盘价标准差,越低越稳;
- 资金流(Flow):用大单动向
dddx代理,反映主力资金进出。
核心代码:
def compute_momentum_volatility(df, window=20):
recent = df.iloc[-window:]
momentum = (recent["close"].iloc[-1] / recent["close"].iloc[0] - 1) * 100
volatility = recent["close"].pct_change().dropna().std() * 100 * np.sqrt(20)
return round(momentum, 2), round(volatility, 2)
# 资金流代理
capital_rows = client.stock_transaction(code=code)
flow = capital_rows[-1]["dddx"]
拿到原始因子后,对每个因子做 z-score 标准化,再按权重合成:
table["score"] = (
0.4 * table["momentum_z"]
- 0.3 * table["volatility_z"] # 波动越低越好
+ 0.3 * table["flow_z"]
)
权重可以根据你的风险偏好调整,这里仅作演示。
三、规则解释层:先让机器自己说人话
在调用大模型之前,先用规则模板生成一版解释。这样即使 LLM 不可用,脚本也能跑通。
def rule_explain(row, all_momentum, all_volatility, all_flow):
code = row["code"]
mom_rank = percentile_rank(row["momentum"], all_momentum)
vol_rank = percentile_rank(-row["volatility"], [-v for v in all_volatility])
flow_rank = percentile_rank(row["flow"], all_flow)
return (
f"[{code}] 综合得分 {row['score']}。"
f"近20日涨幅 {row['momentum']}%(动量超过 {mom_rank}% 样本),"
f"20日波动 {row['volatility']}%(波动控制优于 {vol_rank}% 样本),"
f"大单动向 {row['flow']}(资金流超过 {flow_rank}% 样本)。"
)
对 10 只样本股的运行结果如下(示例数据,非实时):
| 排名 | 代码 | 综合得分 | 规则解释摘要 |
|---|---|---|---|
| 1 | 000001 | 0.52 | 动量中等,波动最低,资金流偏弱,综合强势 |
| 2 | 600519 | 0.47 | 动量强,波动中等,资金流较好,综合中性偏强 |
| 3 | 300750 | 0.42 | 动量最强,但波动也高,资金流入明显 |
| 8 | 601012 | -0.36 | 动量较强,但资金流大幅流出,拖累得分 |
| 10 | 002230 | -1.02 | 资金流排名最低,综合弱势 |
四、LLM 增强解释:给理由加一点"风险意识"
规则模板能保证稳定输出,但容易像报告。接入大模型后,可以要求它:
- 说明得分高/低的主要原因;
- 指出潜在风险;
- 不给出买入/卖出建议;
- 控制在 80 字以内。
Prompt 模板:
你是一名量化研究员,请用 2~3 句话向普通投资者解释下面这只股票的多因子得分含义。
股票代码:{code}
近20日涨幅:{momentum}%
20日年化波动:{volatility}%
大单动向:{flow}
综合得分(z-score 加权):{score}
要求:
1. 说明得分高/低的主要原因;
2. 指出潜在风险;
3. 不要给出买入或卖出建议;
4. 控制在 80 字以内。
如果你的环境没有配置 LLM_API_KEY 和 LLM_BASE_URL,脚本会自动退回规则解释,保证可复现。
五、完整可运行脚本
依赖安装:
pip install mairui pandas numpy requests
核心拉数与初始化:
import os
import pandas as pd
import numpy as np
import mairui
licence = "<你的证书>" # 演示证书,请替换成你自己的正式证书
client = mairui.Client(licence)
# 日线历史
rows = client.stock_history(
code="600519", period="d",
st="20260101", et="20260814", dividend="n"
)
df = pd.DataFrame(rows)
df = df.rename(columns={
"t": "date", "o": "open", "c": "close",
"h": "high", "l": "low", "v": "volume"
})
脚本已整理到本系列 Demo 目录,包含:
build_score_table():拉数据、算因子、合成得分;rule_explain():规则解释模板;llm_explain_prompt()+call_llm():LLM 增强入口。
六、使用边界与常见坑
- 因子权重不是越复杂越好:本文用 0.4/0.3/0.3 固定权重,实盘建议做稳健性检验;
- z-score 对异常值敏感:如果样本中有涨停/跌停股,可能需要 winsorize;
- 资金流代理有局限:
dddx只是大单动向的一种口径,不能等同于"主力一定看好"; - 解释层不能替代决策:AI 只是帮你把数字说出来,买卖判断仍要人来做;
- 不要忘记交易成本:高频调仓下,万 3 佣金 + 千 1 印花税会显著侵蚀收益。
小结
多因子打分解决的是"哪只股票更好",解释层解决的是"为什么它更好"。对量化研究者来说,后者往往更难——你要把冰冷的 z-score 翻译成能让人信服、也能让自己复盘时还记得逻辑的话。
AI 在这里的作用不是创造理由,而是把已有理由组织成可读的语言。规则模板保证稳定性,LLM 增强保证自然度,两者结合才是可持续的工作流。
下篇预告:【AI+量化实战 #09】收盘后还在手动复盘?用 Python 自动生成一页 AI 日报。
想复现本文代码? 麦蕊智数 SDK 提供 A 股实时/历史行情、资金流向等数据,把本文的因子模型跑起来只需要一个证书。
免费领取证书路径:访问 www.mairuiapi.com → 「请求证书」→ 「证书获取」→ 「免费版」,邮箱验证后即可开始测试。
代码与接口文档参考:见官网 麦蕊智数 www.mairuiapi.com 站内「API 文档」与「证书获取」(免费版 500 次/日,邮箱验证即领)



