ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

用Python打造A股量化选股工具包:10大策略整合实践

用Python打造A股量化选股工具包:10大策略整合实践 简介面向A股个人投资者与量化初学者的Python选股工具包基于TuShare获取实时行情与基本面数据内置10种常见技术选股逻辑如250日均线突破、平台突破、回踩均线、停机坪形态、低ATR波动筛选、持续上涨趋势识别等适合快速验证个人选股思路同时也可作为初学者理解策略模块设计的参考。资源共27个文件以17个Python脚本为主配合图片png/jpg、依赖清单、配置文件及Markdown说明压缩包仅1.96MB。脚本按职责独立封装数据获取、SQLite本地存储、策略模块、回测统计、流程控制、买卖信号触发等方便灵活组合与快速替换。目前已有103人学习下载读者可获得从数据采集、本地存储、策略回测到交易信号生成的完整工具链模块化设计便于二次开发扩展新策略适合有一定Python基础的投资者快速搭建自己的选股系统。 搞了半年多的A股量化选股工具包终于把10个策略脚本整合到一个项目里了。先说说这东西是干什么的每天收盘后自动拉取全市场A股的行情、财务和交易数据用10个不同的策略分别跑一遍筛选逻辑输出符合各策略条件的股票清单和打分排名第二天开盘前直接看结果就行。说白了就是把我以前每天早上手忙脚乱翻十几个页面的人工选股流程固化成一套可以重复执行的Python脚本。这套工具包适合谁参考如果你有一定Python基础想用代码替代手工筛选或者刚接触量化选股想知道一个完整的选股工具包是怎么搭起来的这篇内容应该对你有用。下面的内容会从策略逻辑、代码实现、回测验证到常见坑位一点点拆开讲清楚。需要先说明的是这套工具包只负责选股信号和排名不涉及自动下单所有结果都需要你自己二次判断。我也不是荐股文章里不会出现任何具体标的推荐只会讨论方法和代码。1. 为什么做这个工具包从手工筛选到策略代码化1.1 手工选股的痛点与策略固化的价值以前每天选股的流程是这样的先看涨幅榜、换手率再逐个翻F10看财务数据、股东变化遇到符合形态的还要切到K线图上确认一下均线结构。一轮下来少说大半个小时而且很容易漏掉一些不在榜单里的票。最大的问题其实不在时间而在纪律——连续跌几天之后再看什么票都觉得危险连续涨几天之后又容易把看得顺眼当成买入理由。情绪一上来所谓的选股规则全被抛到脑后了。所以我想做的第一件事不是把投资水平提升到多高而是把按规则选股这件事固化下来。规则一旦写进代码它就不会受情绪影响市盈率超过某个阈值就剔除不管这个票当天涨得多漂亮均线死叉就标记风险不因为它上一周涨得不错就选择忽略。代码化选股的核心价值是让你的策略从模糊的感觉变成明确的、可回测的、可复现的规则。这一点在行情波动大的时候体会尤其明显手动的筛选在恐慌行情里基本就是摆设脚本反而能一丝不苟地执行预设逻辑。1.2 工具包的整体架构与模块划分这个工具包采用了一个很朴素的模块化结构所有策略脚本放在strategies目录下公共函数放在common模块里数据缓存、日志、输出报告各归各的。结构如下quant_stock_selector/ ├── common/ │ ├── data_loader.py # 数据获取与缓存 │ ├── indicators.py # 技术指标计算 │ └── utils.py # 通用工具函数 ├── strategies/ │ ├── pe_low.py # 低市盈率策略 │ ├── dividend.py # 高股息率策略 │ ├── small_cap.py # 小市值策略 │ ├── momentum.py # 动量策略 │ ├── ma_cross.py # 均线突破策略 │ ├── rsi_reversal.py # RSI超跌反弹策略 │ ├── volume_surge.py # 成交量异动策略 │ ├── growth.py # 净利润增速策略 │ ├── capital_flow.py # 资金流向策略 │ └── multi_factor.py # 多因子打分策略 ├── main.py # 选股主流程 ├── report.py # 结果输出与汇总 └── config.yaml # 全局配置模块化的好处很明显新增一个策略只需要在strategies里加一个文件实现一个统一接口剩下的数据获取、结果输出、日志记录全部复用公共模块。后面想调整某个策略的阈值也不需要动主流程改配置或者改单个策略文件就行。这个设计后来帮我省了不少事因为策略迭代的频率远比你想象得高有时候一周就能冒出好几个想法要验证。2. 10种策略的选股逻辑与Python实现要点2.1 价值类策略低市盈率与高股息率低市盈率策略的逻辑很简单就是找利润不差但市场给的价格相对便宜的股票。它的假设是市场短期会情绪化定价但长期会回归基本面所以买入估值洼地有机会获得估值修复的收益。实现上先剔除亏损股PE为负的再对PE做升序排列取头部若干只。有一个容易被忽略的细节PE用的是滚动市盈率TTM而不是静态市盈率因为TTM用的是最近四个季度净利润之和能更及时反映最新盈利状况尤其是一季报或者中报刚出的时候静态PE的数据往往是滞后的。高股息率策略关注的是现金分红能力。代码里用过去12个月的每股累计分红除以最新股价来计算股息率然后设定一个门槛值比如股息率大于3%才进入候选池。这个策略的隐性要求是公司愿意且有能力持续分红所以我会额外加一个条件过去三年每年都实施了分红。这个条件的筛选能力比单纯的股息率门槛强很多因为A股里不少公司一年分红一年不分的稳定性没法保证光看一年的股息率很容易踩雷。2.2 趋势与动量类策略均线突破与相对强弱均线突破策略是技术派的老底子了。我实现的是双均线系统短期均线上穿长期均线金叉时标记买入信号下穿死叉时标记卖出信号。在选股场景里我不会直接看信号当天是否金叉而是看最近5天内是否发生过金叉并且要求短期均线仍在长期均线上方。这么处理是为了避免信号刚生成就追高给它一个缓冲窗口兼容回踩确认的进场方式实战中比单纯追当日金叉位要从容不少。动量策略则完全不同它不关心趋势是否刚转折而是看谁涨得最凶。经典做法是取过去60个交易日的累计涨幅作为动量分数然后排序选出动量最强的股票。这个策略在A股单独用效果不太好因为市场风格切换很快追高容易接盘所以我把它和其他因子组合使用很少单独作为选股依据。动量因子更适合用来做排序打分而不是做硬性的入选条件。2.3 反转与量能类策略RSI超跌与成交量异动RSI超跌反弹策略针对的是短期跌过头的情况。RSI小于30通常被视为超卖区我会筛选出RSI进入超卖区但基本面没有明显恶化的股票这类策略赚的是情绪修复的钱。实际操作中要格外注意一点超跌的票有相当一部分是基本面出了问题的所以这个策略必须叠加财务过滤条件。我一般要求净利润同比降幅不超过某一阈值比如20%不然很容易接住下落的刀。这是一条很重要的经验光看技术指标做反转策略在A股里会死得比较难看。成交量异动策略关注的是量能变化。我定义了一个量比指标用当日成交量除以过去5日平均成交量量比大于1.5且股价上涨的股票说明有资金在主动介入会被标记为关注对象。这个策略单独看太敏感任何突发事件都可能造成放量所以我会在输出结果时把量比和涨幅、换手率放在一个表格里展示让人工判断有足够的信息。这种策略的输出形态应该是提示而不是结论。2.4 成长与资金类策略净利润增速与资金流向净利润增速策略是成长股筛选的经典方式。我用最新一期财报的净利润同比增长率作为核心指标同时要求营收增速也保持为正避免单靠非经常性损益造成利润虚高。还有一个我后来加的重要条件剔除掉净利润绝对值规模太小的公司因为基数太小的话增速百分比没有意义比如从1万元涨到2万元增速100%但这个数字毫无参考价值。实际操作中我会加上归母净利润绝对值大于5000万这样的门槛把基数太小的直接过滤掉。资金流向策略在A股语境下比较特殊因为公开数据里并没有真正的资金流向各家平台计算的主动买入金额算法也不一样。我的做法是退而求其次用大单成交净额作为代理指标再叠加近期主力净流入占比这个复合条件。严格来说这不算精确的主力资金跟踪但作为选股时的参考信号聊胜于无我通常把它和其他因子配合使用。注意不要迷信单一资金数据来源不同平台给的净流入数字经常打架这是数据口径本身的问题。2.5 多因子打分与综合策略单因子的有效性总是有周期的所以我做了一个多因子打分策略作为压轴将市盈率倒数、股息率、动量、波动率、ROE等5个因子做标准化处理后加权求和得到每个股票的综合得分。权重的设置一开始我凭经验拍脑袋后来改成用历史数据做因子IC分析把IC值比较稳定的因子权重调高一些。这个策略的价值不是某个因子多厉害而是通过分散因子来源降低单一因子失效带来的风险。多因子策略的具体实现里标准化这一步很容易出问题有的因子是越大越好比如ROE有的因子是越小越好比如市盈率。统一处理方式是对因子值做rank排序再映射到0到1区间这样所有因子的方向就一致了后续加权求和也更有意义。实现时要注意每个因子的计算口径尤其是波动率的计算要用对数收益率不能用百分比收益率的简单标准差否则结果会失真。3. 核心脚本实现与每日自动运行3.1 数据获取、清洗与本地缓存数据是整个工具包的地基我在数据获取上踩过不少坑。早期的方案是直接用第三方库的实时接口拉数据结果经常遇到限流、字段缺失、编码错误等问题。后来改成了盘中抓取本地缓存的方案每个交易日收盘后拉一次全量数据保存到本地SQLite数据库选股脚本只读本地数据不再实时请求网络。这样不仅速度快也方便后续追溯历史结果回测的时候直接查数据库就行。清洗环节有三个必做的步骤去重、去ST、剔除上市不足60个交易日的新股。ST股票在A股有特殊的涨跌幅限制选股逻辑对它实际上是失真的所以直接剔掉。上市不足60天的新股没有足够的历史数据很多指标算不出来也一并过滤掉。这三个过滤条件写在数据加载模块里所有策略自动生效不用每个脚本都重复写一遍。我见过不少新手把清洗逻辑散落在各个策略文件里后面维护起来简直是一场灾难。3.2 选股主流程与策略接口设计主流程main.py的逻辑其实很薄核心思想是策略即函数每个策略文件实现一个统一的process(df) - df接口传入清洗后的全市场数据返回带标记和排序的结果。主流程做的事情就是遍历strategies目录下的所有策略文件逐个执行然后把结果汇总到一个总的Excel报告里。这样每个策略都是独立的互不影响改一个策略不会弄坏另一个。我贴一段低市盈率策略的核心代码作为例子import pandas as pd def process(df: pd.DataFrame, cfg: dict) - pd.DataFrame: # df: 全市场数据, 包含 code, name, pe_ttm, close 等字段 df df[df[pe_ttm] 0] # 剔除亏损股 df df[df[pe_ttm] cfg[pe_threshold]] # 市盈率上限 result df.nsmallest(cfg[top_n], pe_ttm) result result[[code, name, pe_ttm, close]].copy() result[strategy] PE_LOW result[rank] range(1, len(result) 1) return result这里有一个容易被新手忽略的点cfg[pe_threshold]和cfg[top_n]从config.yaml读取而不是直接写死在代码里。参数和逻辑分离的好处是调参的时候不用改代码改一下配置文件重新跑就行后续做参数敏感性分析也方便得多。另外nsmallest这个方法在处理全市场几千只股票时性能足够但如果数据量再大一个量级建议改成先排序再取前N行的写法效率会更好。3.3 每日自动运行与结果播报自动运行部分用系统自带的任务计划程序就行Windows下是任务计划Linux下是crontab不需要额外的调度框架。我自己的节奏是每个交易日晚上8点跑一次数据更新8点10分跑选股主流程生成报告后推送到手机。推送我用了一种特别简单的实现生成报告后自动发送到钉钉机器人或者企业微信机器人只需要一个webhook地址代码里用requests.post就能搞定不需要额外搭建消息服务。每日报告的输出格式我建议固定为两层第一层是汇总页按策略分别列出当日选出的股票数量第二层是明细页每个策略一个sheet包含代码、名称、关键指标和综合排名。这样每天早上扫一眼汇总页就能快速知道每个策略当天有没有选出标的再按需看明细效率会高很多。打印报告的时候我会把每个策略选出来的股票数量做一个统计数量为零的策略会单独标红提示防止脚本静默跑空数据。4. 回测验证与过拟合防范4.1 低成本回测方案与关键指标选股脚本做出来以后必须回答一个问题这个策略是不是真的有效如果不回测就直接实盘用和闭着眼睛蒙没什么区别。我的做法是先做最朴素的回测在历史数据上模拟每个策略的选股结果假设持有20个交易日计算收益率、最大回撤、胜率等统计指标。虽说这种简化回测不考虑滑点和冲击成本但对于策略有效性的初步判断已经够用了。如果你想做更严格的回测可以考虑把策略迁移到qlib这类开源的量化平台上它提供了标准化的因子和回测基础设施比自己在Excel里折腾高效得多。不过对于初版选股工具包来说先把简化回测跑通更重要。我建议用历史数据把每个策略都回测三年以上时间太短的话无法覆盖不同的市场阶段。A股的市场风格切换特别明显一轮小盘行情、一轮白马行情、一轮震荡市下来策略的短板和优势都会暴露得很充分。回测结果出来后我会重点看两个指标一是策略收益是否稳定二是换手率是否过高。换手率太高的策略实际交易成本会吃掉大部分理论收益这是回测中最容易被忽视的陷阱。回测收益很漂亮但换手率一年十几倍的策略实盘大概率是亏钱的。4.2 参数敏感性分析与过拟合防范参数过拟合是量化选股最容易犯的错误。比如RSI阈值有人会把30改成29、31一个个试最后挑出一个历史回测收益最好的数字这个数字放在未来很可能完全不灵因为它是专门针对历史数据调出来的。防范的方法有两个一是做参数敏感性分析把阈值在合理区间内变动看策略表现是剧烈变化还是相对稳定二是把数据分成样本内和样本外用样本内数据调参用样本外数据验证。我的实操经验是如果一个策略只在某个很窄的参数区间里表现好换个参数就崩这个策略基本可以放弃。真正有生命力的策略参数变化时表现应该整体平滑即使不是最优也不会差太多。这个观察比纠结具体参数值重要得多。每次修改参数之后我都要求自己在项目文档里记录改了什么、为什么改、回测结果如何这样半年后回头看就知道当初的思路是什么而不是面对一堆改了又改的代码无从下手。5. 常见问题与排查技巧实录5.1 数据质量与复权问题量化选股脚本90%的Bug都出在数据上而不是策略逻辑上。最常见的问题是复权处理不当。A股分红送股后不除权和前复权的股价差异很大如果直接在未复权数据上计算均线、涨幅、动量结果会严重失真。我的做法是统一用前复权数据做指标计算因为前复权保证了历史价格连续可比选股回测时口径一致。后复权也能保证连续性但当前价格会变得很大看起来不直观所以统一用前复权。另一个经典问题是历史数据缺失。有些股票中途停牌几个月复牌后的数据点和正常交易日的价格放在一起会让各种移动平均计算产生巨大偏差。遇到这种情况我建议在计算指标前先检查每个股票的有效交易天数低于一定数量的直接跳过。还要注意财务数据有发布延迟的问题一季报一般在4月底才披露如果3月份就用一季报数据做回测等于提前用了未来信息属于典型的未来函数这一点要特别小心。5.2 未来函数与幸存者偏差未来函数是我在回测和实盘对比中吃过亏的重灾区。最典型的就是财务报告延迟问题还有一种是当日收盘后选股、当日价格买入的假设。真实操作中选股是收盘后跑的最早也只能在下一个交易日开盘买入回测如果假设当天就能以收盘价买入收益会被放大而且放大的幅度还不小。解决办法是把回测的买入时间点统一设成信号产生后的下一个交易日开盘虽然这样会牺牲一点理论收益但接近真实得多。幸存者偏差则是另一个隐形的坑如果股票池是用当前还在上市的公司数据构建的那些退市的股票就不会出现在历史回测里这会让回测结果系统性偏高。正确的做法是把历史上曾经存在过的股票都纳入数据范围包括后来退市的。这个问题在大多数免费数据源上都存在需要额外确认数据源的退市股票覆盖情况。我刚开始用免费数据跑回测的时候收益漂亮得像股神后来发现是幸存者偏差在作怪修正之后数据就正常多了。5.3 问题排查速查表我在项目里维护了一个常见问题记录文档把线上遇到的典型问题都记了下来方便以后快速排查现象可能原因排查方向策略结果为空过滤条件过严或数据字段异常先放宽阈值再检查是否ST过滤误伤指标出现NaN数据缺失或上市时间太短检查有效交易天数过滤逻辑回测收益异常高存在未来函数或幸存者偏差核对财务数据时间戳、退市股覆盖报告中的排名不稳定权重因子标准化方式不一致检查rank归一化方向是否统一推送消息失败webhook地址失效重新生成webhook并更新配置这张表是踩坑攒出来的遇到新问题我会随时补进去比翻代码排查省力不少。另外我还有一个习惯每次跑完选股脚本都会顺手把当天的全市场截面数据存一份快照保留时间戳。这样如果某个策略在某个时间段突然失效可以回溯到当时的市场环境去复现和分析而不是只能看到当前的情形。最后再分享一个我自己体会很深的东西这套工具包的真正价值不在策略本身的胜率而在于它把选股过程变成了一个可审计的流程。以前有人问我你怎么选股的我只能说个大概方向现在我可以直接打开报告说清楚每个策略在什么条件下选出了什么股票。如果哪个月账户跑输大盘我还能翻出历史选股记录复盘是市场风格问题还是策略失效问题一目了然。这个能力我觉得是所有想长期和量化打交道的人最应该先建立起来的。工具包本身还在持续迭代下一个想加进去的方向是持仓组合的风险暴露分析等做完再单独写一篇。本文还有配套的精品资源点击获取
返回列表