多代理AI选股筛选器:从架构设计到投资组合构建的工程实践
1. 从零拆解一个AI选股筛选器的设计思路第一次看到“设计基于代理的人工智能筛选用于投资组合投资”这个题目很多人脑子里蹦出来的第一反应是“用AI炒股”。这个理解方向没错但太粗糙了。真正落到工程实现上它要解决的核心问题其实是如何让多个具备自主决策能力的智能体各自从不同维度对全市场标的进行筛选最终汇总成一个可执行的投资组合。这里面有三个关键词需要先掰开揉碎代理、人工智能筛选、投资组合。代理也就是Agent在人工智能语境下指的是一种能感知环境、自主决策并采取行动的计算实体。放到投资场景里一个代理可能专门负责看财报数据另一个代理专门盯量价关系还有一个代理负责监控宏观指标。它们各自独立工作互不干扰但最终要把结论汇总。这跟传统的单模型选股有本质区别——单模型是一把尺子量所有人多代理是多个专家各看各的最后开会投票。人工智能筛选指的是用机器学习、深度学习或者规则引擎从几千个标的中快速缩小范围。A股五千多个股票美股上万你不可能一个个看。筛选器的作用就是先粗筛掉90%明显不合格的再把剩下的交给更精细的模型去打分。投资组合则是最终输出。不是选出一只股票就完事而是要决定每只股票配多少仓位、整体风险敞口多大、行业怎么分散。这一步往往被新手忽略但恰恰是决定长期收益的关键。这个项目适合谁如果你是有一定编程基础、对量化投资感兴趣但还没形成完整体系的人这个框架非常适合拿来练手。如果你是完全不懂代码的投资者也可以理解其中的逻辑用现成工具去近似实现。下面我会从架构设计、代理分工、筛选逻辑、组合优化、实操踩坑几个层面把这件事讲透。2. 多代理架构的设计逻辑与分工原则2.1 为什么不用单模型而用多代理单模型选股最大的问题是过拟合和视角单一。你训练一个模型去预测收益率它可能在历史数据上表现很好但一到实盘就崩。原因很简单市场风格会切换今天有效的因子明天可能就失效。单模型很难同时兼顾价值、成长、动量、质量等多个维度强行融合又容易互相干扰。多代理架构的好处在于解耦。每个代理只负责一个维度比如基本面代理只看ROE、毛利率、负债率、现金流技术面代理只看均线、成交量、波动率、相对强弱情绪面代理只看新闻情感、社交媒体热度、分析师评级变化宏观代理只看利率、汇率、PMI、行业景气度每个代理独立输出一个分数或排名最后用一个元学习器或投票机制汇总。这样做的好处是当某个维度失效时你可以单独关掉那个代理不影响其他部分。而且每个代理的逻辑清晰可解释出了问题容易排查。注意代理数量不是越多越好。我试过堆到十几个代理结果汇总层根本学不动噪声太大。一般4到6个代理是比较舒服的区间覆盖主要维度即可。2.2 代理之间的通信与协调机制代理不能各干各的然后简单平均那样跟单模型没区别。它们之间需要有信息交换。常见的设计有两种第一种是黑板模式。所有代理把结果写到一个共享的“黑板”上每个代理可以读取其他代理的结论但决策仍然独立。比如技术面代理发现某只股票放量突破它会把这个信号写到黑板上基本面代理看到后如果该股票基本面也达标就会提高自己的评分权重。第二种是层级模式。有一个主代理负责调度它先让基本面代理粗筛一遍把五千只股票降到五百只再让技术面代理在这五百只里精选最后让组合代理决定仓位。这种模式计算效率高但主代理的调度逻辑需要精心设计。我个人的经验是混合使用效果最好。先用层级模式做粗筛再用黑板模式做精细打分。粗筛阶段用规则引擎就够了不需要上复杂模型速度要快。精细阶段再用机器学习模型允许慢一点。2.3 代理的输入特征工程每个代理的输入特征决定了它的上限。基本面代理的特征相对标准市盈率、市净率、ROE、营收增速、净利润增速、经营现金流/净利润、资产负债率、股息率等。这些数据从财报里直接提取注意要做行业中性化处理否则银行股的市盈率和科技股的市盈率没法比。技术面代理的特征包括5日/20日/60日均线、MACD、RSI、布林带位置、换手率、振幅、过去20日收益率、波动率等。这里的关键是时间窗口的选择。太短了噪声大太长了反应迟钝。我一般用20日作为主窗口辅以5日和60日做交叉验证。情绪面代理比较麻烦需要处理文本数据。新闻标题、分析师报告摘要、社交媒体帖子都要做情感打分。可以用现成的情感分析模型也可以自己标注一批数据训练。注意情感分析的时效性一条三年前的新闻对今天的股价没有影响必须做时间衰减。宏观代理的特征包括十年期国债收益率、美元指数、PMI、CPI、PPI、社融增速等。这些数据频率低但影响大。宏观代理不需要每天输出信号可以按周或按月更新。3. 人工智能筛选的核心算法与实操细节3.1 粗筛阶段规则引擎的快速过滤粗筛的目标是把全市场标的降到可管理的数量比如从5000只降到300只。这个阶段不需要复杂模型用规则引擎就够了。规则的设计要遵循宁漏勿错的原则宁可漏掉一些好股票也不要放进太多垃圾股。常见的粗筛规则剔除ST、*ST、退市风险警示股票剔除上市不满一年的次新股剔除日均成交额低于5000万的流动性差的股票剔除市盈率为负或超过100倍的极端估值股票剔除近两个季度营收或净利润同比下滑超过30%的股票这些规则看起来简单但能过滤掉大量明显不合格的标的。我实测下来一套合理的粗筛规则能把5000只股票降到400只左右耗时不到10秒。提示粗筛规则不要设得太严。我曾经把ROE门槛设到15%结果把很多周期股和困境反转股全滤掉了错过了不少机会。后来改成“ROE连续三年大于8%或最近一年大于12%”覆盖面就合理多了。3.2 精筛阶段机器学习模型的训练与调优精筛阶段用机器学习模型对粗筛后的股票进行打分。常用的模型有XGBoost、LightGBM、随机森林以及近年来流行的Transformer类模型。对于表格数据LightGBM通常是性价比最高的选择训练快、效果好、可解释性强。训练数据的构造是关键。你需要定义标签未来20个交易日的收益率或者未来20个交易日是否跑赢行业指数。前者是回归问题后者是分类问题。我倾向于用分类因为收益率预测的噪声太大分类问题更稳健。特征方面除了前面提到的基本面、技术面、情绪面特征还要加入交叉特征。比如“ROE乘以营收增速”代表高质量成长“换手率除以波动率”代表交易活跃度与风险的比值。这些交叉特征往往比原始特征更有预测力。训练集、验证集、测试集的划分要按时间顺序不能随机打乱。金融数据有时间序列特性随机打乱会导致未来信息泄露模型在测试集上表现虚高。我一般用前70%的时间做训练中间15%做验证最后15%做测试。模型调优的重点是控制过拟合。金融数据信噪比极低模型很容易学到噪声。常用的手段包括限制树的最大深度一般不超过6层、增加最小叶子节点样本数不少于100、使用早停机制、加入L1/L2正则化。3.3 多代理结果的融合策略每个代理输出一个分数后需要融合成一个总分。最简单的做法是等权平均但这样忽略了不同代理在不同市场环境下的有效性差异。更好的做法是动态加权。动态加权的思路是根据最近一段时间每个代理的IC值信息系数即代理评分与未来收益的相关系数来调整权重。IC高的代理权重加大IC低的减小。具体公式[ w_i \frac{IC_i}{\sum_{j} IC_j} ]其中 ( IC_i ) 是代理i在过去60个交易日的平均IC值。为了防止权重波动过大可以加入平滑因子比如用指数移动平均来计算IC。另一种融合策略是分层融合。先让基本面代理和技术面代理各自输出前50名取交集再让情绪面代理对交集内的股票重新排序。这种策略适合代理之间相关性较低的情况。我实测下来动态加权在大多数时候比等权平均好但在市场风格剧烈切换时动态加权会反应滞后。所以我会设置一个权重下限比如每个代理的权重不低于10%避免某个代理被完全忽略。4. 投资组合构建与风险控制4.1 从筛选结果到组合权重筛选器输出的是股票排名但投资组合需要的是权重。从排名到权重中间隔着风险控制。最朴素的做法是等权买入前20名每只5%。但这样会导致行业集中度过高比如前20名全是新能源一旦板块回调整个组合就崩了。更好的做法是风险平价或均值方差优化。风险平价的目标是让每只股票对组合风险的贡献相等。均值方差优化则是在给定风险水平下最大化预期收益。两者都需要估计协方差矩阵而协方差矩阵的估计在股票数量较多时很不稳定。我的做法是分两步走先做行业中性化确保每个行业的权重不超过20%再在行业内做风险平价。这样既分散了行业风险又避免了单只股票权重过大。具体步骤将筛选出的股票按行业分类每个行业分配一个基础权重比如等权分配每个行业5%在行业内根据代理评分和波动率计算个股权重对个股权重设置上限比如单只不超过3%归一化确保总权重为100%4.2 仓位管理与动态再平衡建仓之后不是就不管了。市场在变代理的评分也在变。需要定期再平衡。再平衡的频率很关键太频繁了交易成本高太稀疏了跟不上变化。我一般每两周再平衡一次同时设置触发式再平衡当某只股票的权重偏离目标超过2个百分点时单独调整。再平衡时还要考虑交易成本。A股买卖有佣金和印花税频繁交易会吃掉不少收益。所以再平衡时我会设置一个缓冲区只有当新权重与旧权重的差异超过1%时才交易否则不动。注意再平衡不是越勤越好。我试过每周再平衡结果一年下来交易成本吃掉了3%的收益。后来改成两周一次加上缓冲区成本降到了1%以内。4.3 风险控制的关键指标组合构建完成后需要监控几个关键风险指标指标含义警戒线最大回撤从高点回落的最大幅度超过15%需减仓波动率组合收益的标准差年化超过25%需警惕夏普比率单位风险的超额收益低于0.5需反思行业集中度最大行业权重超过25%需分散个股集中度最大个股权重超过5%需削减换手率年化交易频率超过300%需优化这些指标需要每天监控一旦触发警戒线就要启动相应的风控措施。比如最大回撤超过15%我会把仓位降到70%等回撤修复后再加回来。5. 实操中常见的坑与排查技巧5.1 数据质量问题的排查金融数据最大的坑是数据质量。财报数据可能有错漏行情数据可能有缺失复权因子可能算错。我踩过最惨的一次是某只股票的分红数据没更新导致复权价格算错模型给出了错误的买入信号结果实盘亏了8%。排查数据质量的方法检查每个字段的空值率超过5%的字段要警惕检查极端值比如市盈率超过1000倍的大概率是数据错误检查时间序列的连续性突然跳变的地方要人工核对对比多个数据源不一致的地方以官方披露为准5.2 过拟合的识别与解决过拟合是量化模型最常见的死法。识别过拟合的信号训练集表现极好测试集表现很差模型参数对训练数据极度敏感稍微改一点数据结果大变特征重要性排名中很多特征的经济含义说不通解决过拟合的方法减少特征数量只保留经济含义清晰的特征增加正则化强度使用更简单的模型比如从深度学习换回LightGBM增加训练数据的时间跨度覆盖更多市场环境我个人的经验是如果一个模型在测试集上的夏普比率超过2大概率是过拟合了。真实的量化策略夏普比率在1到1.5之间是比较合理的。5.3 代理之间信号冲突的处理多代理架构下不同代理可能给出矛盾的信号。比如基本面代理说某只股票被低估技术面代理说它正在下跌趋势中。这时候怎么办我的处理原则是分情况讨论如果基本面和技术面冲突优先相信技术面。因为技术面反映的是市场当下的共识基本面反映的是你个人的判断。市场不认你再对也没用。如果情绪面和基本面冲突优先相信基本面。情绪是短期的基本面是长期的。如果宏观代理和所有其他代理冲突降低整体仓位。宏观风险是系统性风险个体股票很难对抗。具体实现上可以给每个代理设置一个置信度分数。当代理之间的分歧超过阈值时自动降低总仓位。比如分歧度超过0.5仓位降到50%。5.4 常见问题速查表问题现象可能原因排查方向解决方法回测收益极高但实盘亏损过拟合或未来函数检查特征是否用了未来数据严格按时间划分数据集组合波动率远超预期行业集中度过高检查行业权重分布加入行业中性化约束换手率异常高再平衡过于频繁检查再平衡频率和缓冲区降低频率加大缓冲区某代理权重持续为0IC值长期为负检查该代理的特征是否失效暂时关闭该代理重新训练数据更新后结果大变数据质量问题对比多个数据源修复数据重新回测模型训练时间过长特征维度太高检查特征数量做特征选择降维6. 从回测到实盘的过渡经验回测漂亮不代表实盘能赚钱。回测和实盘之间隔着滑点、冲击成本、流动性限制三座大山。滑点是你下单的价格和预期价格的差异冲击成本是你的交易本身对市场价格的影响流动性限制是某些股票你想买但买不到足够的量。我的做法是在回测阶段就模拟这些成本。滑点按千分之一计算冲击成本按成交额的万分之一计算流动性限制则设置单只股票单日买入不超过其日均成交额的1%。这样回测出来的结果会更接近实盘。实盘初期我会用小资金试跑比如先用总资金的10%跑一个月对比实盘和回测的差异。如果差异在可接受范围内再逐步加仓。如果差异很大就要停下来排查原因。还有一个容易被忽略的点是心理因素。回测的时候你看到的是曲线实盘的时候你看到的是真金白银的波动。连续亏损几天很多人就扛不住了开始手动干预。我的建议是在实盘之前就写好交易规则然后严格执行。规则之外的干预大概率是负贡献。提示实盘第一年我的手动干预贡献了-5%的收益。后来我把交易权限完全交给系统只在极端情况下才手动介入收益反而稳定了。7. 代理架构的扩展方向这套多代理架构不是一成不变的。随着你对市场理解的深入可以不断扩展。比如加入另类数据代理用卫星图像数据判断零售商的客流用信用卡消费数据判断消费股景气度。这些数据在海外市场已经比较成熟国内也有不少供应商。另一个扩展方向是强化学习代理。传统的代理是基于规则或监督学习的强化学习代理可以通过与市场环境交互自主学习最优的买卖时机。不过强化学习在金融领域的应用还比较早期训练不稳定容易过拟合建议谨慎尝试。还有一个方向是代理之间的对抗训练。让一个代理专门寻找另一个代理的弱点比如一个代理专门识别另一个代理在什么市场环境下会失效。这种对抗机制可以提高整体架构的鲁棒性。我个人目前还在探索的是跨市场代理。A股、港股、美股各自有不同的市场特征用一个统一的代理架构去覆盖多个市场需要处理汇率、交易时间、监管规则等差异。这个方向挑战很大但一旦跑通分散风险的效果会非常明显。最后分享一个小技巧定期给代理做“体检”。每个月检查一次每个代理的IC值、胜率、盈亏比如果某个代理连续三个月表现低于阈值就把它下线重新训练或者替换。代理架构的优势就在于模块化坏了一个换一个不影响整体运转。