全市场4000多只股票,如何在10秒内筛选出今天最值得关注的20只?
这是司南投研系统最核心的设计挑战,也是我在架构阶段花时间最多的问题。
为什么需要三层扫描?
最直接的想法是:把4000多只股票全塞进扫描引擎,每60秒扫一次,出来什么信号就交易什么。这个思路在技术上是行不通的:
- API限流:数据源(akshare/baostock)有调用频率限制。4000只股票 × 每次获取分钟级K线 = 极易触发限流
- 扫描耗时:即使API不限流,4000只股票的完整技术指标计算(MA、MACD、RSI、布林带)至少需要几分钟
- 信号质量:大量边缘标的(换手率极低、价格横盘)参与扫描,产生的信号噪声远大于有效信号
结论很明确:必须先筛选,再扫描。筛选的精度决定了扫描的效率,扫描的效率决定了信号的质量。
三层架构的设计逻辑
第一层:基础池(每周一次,约3000-4000只)
这是最粗粒度的筛选,只做“排除法”:
- 剔除ST股(财务异常,波动规律与正常股票不同)
- 剔除上市不满60天的新股(技术指标数据不足,波动剧烈)
- 剔除市值低于50亿的微型股(流动性差,容易被操控)
这一层的作用是把“明显不合格”的标的排除掉。过滤条件相对固定,不需要频繁调整。
第二层:候选池(每日盘后,约20-50只)
这是整个系统最关键的一层。它要回答的问题是:在3000多只正常股票中,哪些最适合我的波段策略?
我设计了一个五因子评分模型,每只股票都按以下维度打分:
| 因子 | 权重 | 评分逻辑 |
|---|---|---|
| 日均振幅得分 | 30% | 振幅在5%-8%区间得满分,偏离越远得分越低。振幅太小没利润空间,太大说明股价不稳定 |
| 换手率得分 | 20% | 换手率在3%-10%区间得满分。换手率太低没人气,太高可能有主力出货 |
| 成交额得分 | 20% | 成交额越高得分越高(经对数标准化)。保证选出的股票流动性充足 |
| 趋势强度得分 | 20% | 股价在20日均线上方且偏离度在1%-5%区间得满分。既要有上升趋势,又不能过度拉伸 |
| 量价配合度得分 | 10% | 近5日价格上涨时放量、下跌时缩量的程度。量价配合好说明上涨更健康 |
按总分降序排列,默认取前20只。再加上用户自选股(去重),形成最终候选池。
为什么是20只,不是100只?
这是我反复测试后得出的平衡点。候选池越大,第三层扫描耗时越长;候选池太小,可能错过一些潜力标的。20只+自选股的组合,让扫描耗时稳定在10秒以内,同时保持足够的覆盖度。
第三层:交易信号(盘中每60秒)
这是直接产生交易决策的一层。扫描范围只有候选池+自选股,约20-50只,每只股票计算以下指标:
- 买入信号:股价回踩20日均线 + MACD金叉
- 卖出信号:股价触及布林带上轨 或 RSI(14) > 80
- 止损信号:持仓亏损触及-8%硬止损
第三层还内置了频率调节机制:如果连续3次扫描都没有产生任何信号,自动将扫描频率从60秒降到5分钟,节省计算资源。一旦信号恢复,自动切回60秒。
评分模型的可配置设计
实际使用中,不同市场环境下最优的因子权重可能不同。所以第二层的评分模型不是写死的,而是完全可配置的:
- 五个因子的权重可以在前端页面拖拽滑块调整(总和必须等于100%)
- 评分入选数量可以在系统配置页面动态修改
- 每次修改权重后自动保存为新版本,旧版本保留备查
- 浑仪(量化策略Subagent)每月对评分模型做一次回测,评估各因子对策略收益的贡献度,给出优化建议
这意味着你的评分模型可以随着市场变化持续进化,而不是一成不变。
实战效果
在开发阶段,我用历史数据做了一次完整的回测:
- 第一层基础池:约3500只
- 第二层候选池:20只(评分精选)+ 3只(自选股)- 1只(重复)= 22只
- 第三层扫描耗时:平均6.8秒,P95约9.2秒,符合<10秒的设计目标
- 全链路:从基础池更新到交易信号产生,端到端数据流完全闭环
更重要的是,候选池的股票质量明显优于随机抽取——回测显示,候选池等权组合的年化收益率显著高于基础池等权组合,说明第二层的评分筛选确实产生了正向超额收益。
设计启示
三层扫描体系的设计过程,让我深刻体会到AI辅助开发的一个核心原则:
把复杂问题拆解成AI可独立执行的模块。
我不是让AI“设计一个全市场扫描系统”——这个任务太模糊,AI会无从下手。而是把问题拆成:第一层怎么做、第二层怎么打分、第三层怎么扫描,每一层都有明确的输入、处理逻辑和输出。然后让AI逐个模块实现。
这个系统最终能被成功搭建起来,不是因为AI有多强大,而是因为我把正确的问题以正确的方式交给了AI。
下一篇预告:《AI帮我写风控代码:行级锁+事务+幂等处理》