资讯动态

TuShare A股自动选股程序:从数据拉取到信号落地的完整拆解

发布时间:2026/10/17 22:04:32 来源:尧图企业网站定制
简介这是一份面向量化投资初学者与金融数据分析爱好者的Python实战项目围绕TuShare财经数据接口构建A股自动选股系统帮助读者打通数据获取、清洗、策略制定到回测评估的完整链路。资源包共25个文件以17个py脚本为核心涵盖数据抓取、策略实现与回测模块另含requirements.txt依赖清单、README说明文档及少量jpg、png图表压缩包约1.95MB结构清晰便于按模块研读。项目内置多种选股思路如移动平均线交叉、RSI、MACD等技术指标以及突破平台、低ATR、海龟交易、持续增长等策略脚本并配有回测与退出逻辑可直观观察策略在不同市场环境下的表现。目前已有6025人学习下载适合希望将Python编程与金融知识结合、动手搭建个人量化选股工具的开发者参考实践。1. 用 TuShare 搭一套 A 股自动选股程序从数据拉取到信号落地的完整拆解很多人第一次听到「自动选股」脑子里浮现的是满屏 K 线加神秘指标其实落到代码层面它就是把「拉数据 → 算因子 → 过滤 → 输出候选池」这条链路用 Python 串起来。这份基于 TuShare 的 A 股自动选股程序核心价值就在于把这条链路做成了一个能跑、能改、能复现的工程骨架而不是一段只能看不能用的演示脚本。它适合两类人一类是刚接触量化、想搞明白选股程序到底怎么搭的开发者另一类是手里已经有交易逻辑但缺一套稳定数据管道和筛选框架的从业者。下面我按自己拆包复现的顺序把这份资源讲透。2. TuShare 数据接口与选股链路先搞清楚数据从哪来、因子怎么算2.1 为什么选 TuShare 而不是自己爬行情做 A 股选股第一道坎不是策略是数据。自己爬行情页面短期能跑长期必然翻车字段结构一变、请求频率一高脚本就废了。TuShare 这类标准化数据接口的价值是把「日线行情、复权因子、财务指标、股票列表」这些基础数据用统一格式吐出来你只需要关心怎么用不用天天修解析器。这份程序选 TuShare 作为数据源逻辑上是合理的。它覆盖了选股最常用的几类数据日线行情开高低收、成交量额、复权信息、基本面指标市盈率、市净率、市值等、以及股票基础列表。对一套自动选股程序来说这四类数据基本够搭出一个多因子筛选框架。需要提前说清楚一个边界TuShare 的接口有积分门槛不同接口对积分要求不一样。常见做法是先用免费额度能拿到的接口把流程跑通比如日线行情和股票列表等策略验证有效再考虑更高频或更细的财务数据。我一般会建议先把「能拿到什么数据」列成一张表再决定因子怎么设计而不是先想一堆指标最后发现数据拿不到。数据类别典型用途更新频率注意点股票列表确定选股池范围低频注意退市、ST 标记日线行情价格、成交量因子每日需处理停牌与复权复权因子计算真实涨跌幅每日不复权会算出假信号基本面指标估值、市值筛选季度/每日注意财报披露时点2.2 选股链路的四个环节一套自动选股程序拆开看就是四步数据获取、因子计算、条件过滤、结果输出。这份资源的骨架也是按这个顺序组织的我复现时基本没改结构只替换了因子部分。第一步数据获取负责把股票列表和行情拉下来落到本地做缓存。第二步因子计算把原始行情转成可比较的指标比如 N 日涨幅、换手率、均线偏离度。第三步条件过滤用阈值或排序把候选池缩小。第四步输出把结果写成 CSV 或打印出来方便人工复核。import tushare as ts import pandas as pd # 初始化接口token 需替换为自己的 pro ts.pro_api(your_token_here) # 拉取股票基础列表fields 指定需要的字段减少无效传输 stock_basic pro.stock_basic( exchange, list_statusL, # L 上市 D 退市 P 暂停 fieldsts_code,symbol,name,area,industry,list_date ) # 拉取某交易日全部日线行情 daily pro.daily(trade_date20240102) # 合并基础信息与行情得到带行业标签的行情表 merged pd.merge(daily, stock_basic, onts_code, howleft) print(merged[[ts_code, name, industry, close, pct_chg]].head())这段代码的逻辑很直白先拿股票池再拿当日行情最后按ts_code合并。参数上list_statusL只保留正常上市股票避免把退市股混进选股池fields显式指定字段能减少返回体积也避免接口字段变动时整段代码崩掉。trade_date用YYYYMMDD字符串格式这是 TuShare 的约定写成日期对象会报错这点新手很容易踩。2.3 因子计算把行情转成能排序的数字拿到行情只是原料选股真正依赖的是因子。这份程序里常见的因子包括动量类近 N 日涨幅、流动性类换手率、成交额、估值类市盈率、市净率。计算时最关键的一点是复权不复权的价格在除权除息日会出现跳空直接算涨幅会得到假信号。# 计算 20 日动量因子当前收盘价相对 20 日前收盘价的涨幅 def momentum_factor(df, window20): df df.sort_values(trade_date) df[mom20] df[close].pct_change(window) return df # 按股票分组计算避免不同股票之间串行 daily_grouped daily.sort_values([ts_code, trade_date]).groupby(ts_code) daily_grouped daily_grouped.apply(lambda x: momentum_factor(x)).reset_index(dropTrue) # 过滤掉动量因子为空上市不足 20 日的股票 candidates daily_grouped.dropna(subset[mom20])这里pct_change(window)算的是相对 window 期前的涨幅groupby(ts_code)保证每只股票单独计算不会把 A 股票的价格和 B 股票混在一起。dropna那一步是必须的新股上市不足 20 日时因子为空不处理会在排序时出问题。参数window我一般设 20 或 60对应一个月和一个季度的动量具体取值要看策略周期没有万能值。3. 从脚本到可复用程序模块拆分与批量选股落地3.1 把单文件脚本拆成三层结构原始脚本能跑但所有逻辑堆在一个文件里改一处容易牵动全身。我复现时做的第一件事是拆成三层数据层、因子层、策略层。数据层只管拉数和缓存因子层只管把行情转成指标策略层只管按条件筛。这样换数据源只动数据层换因子只动因子层互不干扰。# data_layer.py import tushare as ts import pandas as pd import os CACHE_DIR ./cache def get_daily(trade_date, token): 带本地缓存的日线获取避免重复请求 cache_file os.path.join(CACHE_DIR, fdaily_{trade_date}.csv) if os.path.exists(cache_file): return pd.read_csv(cache_file) pro ts.pro_api(token) df pro.daily(trade_datetrade_date) os.makedirs(CACHE_DIR, exist_okTrue) df.to_csv(cache_file, indexFalse) return df缓存这一步看着简单实际很关键。TuShare 接口有调用频率限制反复拉同一天数据既浪费额度又慢。用trade_date做文件名缓存第二次直接读本地速度差一个数量级。参数上CACHE_DIR建议放在项目目录下别放临时目录否则重启就没了。3.2 批量选股一次跑多天、多因子单日选股只能看一天结果实际用的时候往往要回看一段时间验证策略稳定性。批量选股的做法是把交易日列表循环起来每天跑一遍筛选最后汇总。# strategy_layer.py import pandas as pd def select_stocks(daily_df, top_n20): 按动量因子排序取前 top_n 只 df daily_df.dropna(subset[mom20]) # 先按动量降序再按成交额降序避免同动量时无法区分 df df.sort_values([mom20, amount], ascending[False, False]) return df.head(top_n)[[ts_code, name, industry, close, mom20]] def run_backtest(trade_dates, token): 批量跑多个交易日汇总每日候选池 results {} for date in trade_dates: daily get_daily(date, token) # 这里需要先补算因子实际项目里因子计算单独一层 picked select_stocks(daily) results[date] picked return resultsselect_stocks里用mom20主排序、amount次排序是为了处理动量相同的情况否则排序结果不稳定每次跑出来顺序可能不一样。top_n控制候选池大小设太小容易漏掉机会设太大失去筛选意义我一般设 20 到 50 之间。批量跑的时候要注意因子计算需要历史数据单日行情算不出 20 日动量所以真实项目里因子层要单独维护一个滚动窗口不能只拿当天数据。3.3 输出与复核别让程序替你拍板程序输出的是候选池不是买入指令。我习惯把结果写成 CSV带上股票代码、名称、行业、因子值然后人工过一遍。有些信号明显是数据问题导致的比如某只股票因为停牌复牌出现异常涨幅程序会把它排到前面但人工一眼就能排除。# 输出候选池带日期后缀方便归档 def save_result(picked, date): out_file f./output/picked_{date}.csv picked.to_csv(out_file, indexFalse, encodingutf-8-sig) print(f{date} 候选池已保存共 {len(picked)} 只)encodingutf-8-sig是为了 Excel 打开不乱码这个细节很多人忽略结果中文股票名全是问号。输出目录建议单独建别和缓存混在一起方便清理。4. 避坑与排查这套选股程序最容易翻车的五个地方4.1 现象选出来的股票全是同一行业原因通常是因子单一只用了动量或涨幅而某个行业当天整体大涨导致候选池被一个行业包揽。解决方式是在筛选条件里加行业分散约束比如每个行业最多取 3 只或者引入行业中性化处理把行业涨幅从个股因子里剔除。4.2 现象回测结果好得离谱原因多半是用了未来数据。比如用当天收盘价算因子又用当天收盘价买入等于偷看了未来。正确做法是 T 日收盘后算因子T1 日开盘或收盘执行。检查方法是把因子计算里的数据截断到 T-1 日看结果是否大幅回落如果回落明显说明之前用了未来数据。4.3 现象接口报错「抱歉您没有访问该接口的权限」原因是 TuShare 部分接口需要积分免费额度不够。解决方式是先确认当前积分能访问哪些接口把程序里用到的接口列出来逐个测试。常见做法是先用日线行情和股票列表把流程跑通财务类接口等积分够了再接入不要一上来就依赖高门槛接口。4.4 现象停牌股票混进候选池原因是停牌期间行情数据缺失或为 0因子计算出异常值。解决方式是在筛选前过滤掉成交额为 0 或换手率为 0 的股票同时检查股票列表里的上市状态。停牌股复牌后往往有补涨补跌程序如果不排除会把这类噪声当成信号。4.5 现象每天跑出来的结果顺序不一样原因是排序字段有并列值Pandas 默认排序不稳定。解决方式是加次级排序键比如成交额或股票代码保证同样条件下输出顺序一致。这个坑不影响选股逻辑但会影响你对比不同日期的结果排查起来很费时间。提示以上五个问题里未来数据是最隐蔽也最致命的建议每次改完因子都做一次「截断测试」确认没有用到当天之后的数据。5. 进阶技巧用滚动窗口和因子分层把选股程序做稳程序能跑之后下一步是让它稳。我自己的习惯是加两个东西滚动窗口和因子分层。滚动窗口解决的是「因子需要历史数据」的问题不能只拿当天行情算。做法是维护一个最近 N 个交易日的行情缓存每天增量更新算因子时从缓存里取窗口数据。# 维护滚动窗口增量更新最近 60 个交易日行情 def update_window(trade_date, token, window60): 拉取当日行情并追加到窗口缓存保留最近 window 天 daily get_daily(trade_date, token) window_file ./cache/window.csv if os.path.exists(window_file): old pd.read_csv(window_file) combined pd.concat([old, daily], ignore_indexTrue) else: combined daily # 按交易日去重后保留最近 window 个交易日 dates sorted(combined[trade_date].unique())[-window:] combined combined[combined[trade_date].isin(dates)] combined.to_csv(window_file, indexFalse) return combined这段逻辑的关键是「按交易日去重后截断」避免重复追加导致窗口膨胀。window60对应约三个月够算常见的动量因子。参数上窗口大小要大于你最大的因子周期比如用 60 日动量窗口至少 60 天建议留 20% 余量。因子分层是另一个提稳手段。把股票按因子值分成若干层观察每层的后续表现比只看 Top N 更能判断因子是否有效。常见做法是分 5 层看最高层和最低层的收益差如果差距不明显说明这个因子在当前市场环境下区分度不够需要换因子或调参数。分层因子值范围用途第 1 层最低 20%对照组观察反向表现第 3 层中间 20%基准判断因子单调性第 5 层最高 20%候选池来源从那以后我每次改因子都强制走一遍「截断测试 分层观察」确认没有未来数据、因子单调性正常才敢把结果拿去用。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑