Rockyzsu/stock / 选股分析
选股与分析:因子筛选、涨停池、K 线形态与回测口径
这个项目里「选股」不是一个功能,而是四条互不相通的链路:①基于 Tushare 基础表的因子筛选(select_stock.py 为主);②东方财富的五类涨停池(涨停、强势、炸板、跌停、昨日涨停);③用 talib 做的 K 线形态识别;④backtest/ 里的 backtrader 回测示例。
四条链路的成熟度差别很大。因子筛选是主脚本(select_stock.py 545 行),但它标注「适用 tushare 0.7.5」且导入期就会报错;涨停池采集是完整可读的工程代码;K 线形态依赖本地 C 库;回测只有 5 个示例文件、数据路径还指向作者本机。本页把这四条链路各自的真实状态、字段口径与可信度边界一次讲清。
四条链路
选股与分析的四条链路有什么差别:成熟度对比
| 链路 | 主脚本 | 数据来源 | 输出 | 当前状态 |
|---|---|---|---|---|
| ① 因子筛选 | select_stock.py(545 行,注释标注「适用 tushare 0.7.5」) | Tushare 老接口 ts.get_stock_basics() 生成的基础表 + ts.get_k_data() 历史行情 | 按条件筛出的股票清单,可落 MySQL 表 bases 与本地 bases.csv | 导入期即报错:from configure.settings import get_engine 但该符号不存在 |
| ② 因子筛选(分析侧) | StockAnalyze.py(274 行,@feature: 收盘事后分析) | Tushare + MySQL(db_daily / db_stock / db_zdt) | 成交量分布、涨停位置、个股盈亏、次新涨停、年度涨幅 | 部分函数可读;第 234 行有一处未导入的 get_engine 调用 |
| ③ 涨停与强势池 | datahub/dfcf_hot_block.py、datahub/zdt.py | 东方财富 push2ex 五类池接口 + 金融界涨停数据 | 写入 db_zdt(if_exists='fail') | 结构完整;同一天无法重跑 |
| ④ K 线形态识别 | k-line/recognize_form.py、k-line/search_target.py、k_line.py | Tushare/akshare 日线 + talib 形态函数 | 形态命中的股票清单与 K 线图 | 依赖本地 C 库;k_line.py 导入了不存在的配置常量 |
| ⑤ 基金与 LOF | fund/ 45 个脚本 | 集思录、天天基金、雪球、上交所 | 份额变动、折溢价率、持仓股 | 以爬虫为主,站点改版即失效 |
| ⑥ 回测 | backtest/ 5 个文件 | 本地 CSV(datapath.py 指向作者本机路径) | 控制台打印初始/结束资金 | 仅示例,无绩效统计与成本模型 |
先看清一件事:这六条链路没有共享的信号层。因子筛选的结果不会自动流进回测,回测结果也不会回流到监控。每条链路各自读库、各自输出。要串起来,得你自己写中间的粘合层。
因子维度
因子从哪里来:八个维度与它们的口径风险
| 因子维度 | 字段来源 | 筛选方式 | 口径注意点 | 适用场景 |
|---|---|---|---|---|
| 市盈率(pe) | ts.get_stock_basics() 的快照字段 | 条件比较,代码里会自动剔除 pe == 0 的样本再算均值 | 亏损股 pe 为 0 或负,直接取均值会被污染 | 价值型初筛 |
| 流通市值 / 流通股本 | 同基础表 | 排序取前 N | 老接口是全市场一次性快照,字段口径与新版 Pro 不同 | 小盘/大盘风格切换 |
| 股东户数 | 基础表 + 股东信息脚本(shareholder_info.py) | 按户数变化筛选 | 股东数需按期对比,单期快照无意义 | 筹码集中度观察 |
| 基金持股数 | 基础表字段 + 基金持仓脚本 | 按持股数量或比例筛 | 基金季报披露滞后,最新一期未必是当下持仓 | 机构持仓跟踪 |
| 上市时间(timeToMarket) | 基础表 | 按日期比较筛次新股 | 次新定义随行情变化,代码里用的是硬编码起始日期 | 次新股策略 |
| 地域(area) | 基础表 | 按地区分组计数或筛选 | 字段为中文地名,跨数据源拼接时容易对不上 | 地域分布统计 |
| 涨跌幅 / 连板数 | 东财涨停池接口 | 按池子类型直接取名单 | 强势池与涨停池口径不同,不能混用 | 短线强度观察 |
| K 线形态 | talib 形态函数 | 形态函数返回非零即命中 | 形态函数对参数与复权方式敏感 | 技术形态筛选 |
一个容易忽略的细节:select_stock.py 的筛选依赖一张叫 bases 的基础表(MySQL)或 bases.csv(本地)。这张表由它自己的 local=True 分支生成,而 bases.csv 在 .gitignore 里、仓库中没有。另外 6 个脚本也读这个文件,所以它是整条链路的前置条件。
涨停池
五类涨停池怎么选:短线研究最实用的现成数据
| 池子类型 | 接口函数 | 代表什么 | 典型用途 |
|---|---|---|---|
| 涨停池 | stock_zt_pool_em | 当日封住涨停的股票 | 涨停强度、连板梯队 |
| 强势池 | stock_zt_pool_strong_em | 未涨停但强势(涨幅居前)的股票 | 提前发现接力标的 |
| 炸板池 | stock_zt_pool_zbgc_em | 曾涨停但打开(炸板)的股票 | 情绪退潮信号 |
| 跌停池 | stock_zt_pool_dtgc_em | 当日封住跌停的股票 | 风险扩散观察 |
| 昨日涨停池 | stock_zt_pool_previous_em | 前一交易日涨停的股票及其当日表现 | 打板策略的次日溢价统计 |
这五类池子是做短线研究最实用的现成数据,官方接口以 push2ex.eastmoney.com/getTopic*Pool 提供,脚本里还有一个 get_ut_value() 专门抓接口所需的 ut 参数——抓不到时会给作者的企业微信发一条「eastmoney ut None」的告警。落库用的是 if_exists='fail',意味着同一天第二次运行会直接抛错,重跑前要先删表。
回测可信度
「有回测代码」和「收益可信」的区别:六项逐条对比
| 链路 | 数据成本 | 交易成本 | 滑点 | 样本外 | 未来函数风险 | 说明 |
|---|---|---|---|---|---|---|
backtest/ 示例 | 未处理(读本地 CSV) | 仅 1 处 setcommission(0.001 / 0.002 / 0.005 不等) | 未建模 | 未做 | 存在(示例无对齐检查) | 5 个文件都是教学示例,不适合直接用于评估策略 |
select_stock.py 的筛选 | 依赖全市场快照 | 不涉及(只出清单) | 不涉及 | 未做 | 低(纯横截面筛选) | 输出是股票清单,不是收益曲线 |
StockAnalyze.py 的统计 | 读已落库数据 | 不涉及 | 不涉及 | 未做 | 中(多为事后统计,无前视问题,但无验证) | 属描述性统计,不是策略验证 |
recordMyChoice.py 的实盘跟踪 | 依赖实盘成交 | 真实成本(券商实际收取) | 真实滑点 | 天然样本外 | 无 | 这是仅有带真实成交的记录工具,但样本量取决于你自己的交易次数 |
utils/profit_compare.py | 读持仓文件 | 不涉及 | 不涉及 | — | 无 | 只做两个标的的盈亏对比 |
本站不做任何绩效判断,因为仓库里没有任何一份回测报告。上表只是把「如果要评估收益,这四条链路分别缺什么」列清楚。一句话总结:这个仓库提供的是信号生成与记录工具,不提供收益证明。回测链路本身也只是教学示例。
选型清单
想做什么该看哪个脚本:七种目的与前置条件
| 你的目的 | 看哪个脚本 | 前置条件 | 预期输出 | 注意点 |
|---|---|---|---|---|
| 按基本面因子筛一批股票 | select_stock.py | 基础表 bases(MySQL 或 CSV)+ Tushare token | 筛选后的股票清单 | 导入期报错需先修 get_engine 导入 |
| 统计某段时间的成交量分布 | StockAnalyze.py | MySQL 中的日线库 | 成交量与占比统计 | 第 234 行需修未导入的 get_engine |
| 拿涨停/强势池名单 | datahub/dfcf_hot_block.py | 可访问东财接口 | 当日五类池数据入库 | 同一天重跑会因表已存在报错 |
| 识别 K 线形态(三只乌鸦等) | k-line/recognize_form.py | talib 本地 C 库 + 日线数据 | 命中形态的股票与 K 线图 | 形态函数对复权敏感 |
| 看次新股涨停强度 | analysis/get_zt_info | 分析库中的次新基础表 | 强度统计 | analysis/ 以 Notebook 为主 |
| 记录并复盘自己的选股 | recordMyChoice.py | Excel 文件 + Tushare | 每只自选股的收益跟踪 | 依赖本地 Excel 模板 |
| 导入券商交割单 | utils/delivery_order.py | 券商导出的 CSV(GBK 编码) | 交割记录入库 | 按券商分表,国金与华宝各一张表 |
建议的入门顺序:先跑 datahub/dfcf_hot_block.py(无登录态、结构最完整),理解「抓取 → 落库」;再改 select_stock.py 的筛选条件(需要先修导入)。不要一上来就从回测开始——那是最薄的 5 个示例文件。
FAQ
关于 Rockyzsu/stock 的常见问题
它内置策略吗?
select_stock.py 为什么跑不起来?
from configure.settings import get_engine,而 configure/settings.py 里 get_engine 只是 DBSelector 类的方法、不是模块级函数,所以直接 ImportError;②第 8 行 import Queue,这是 Python 2 的模块名,Python 3 下应是 queue。修完这两处才会进入运行期。完整清单见报错排查页。因子筛选用的是什么数据?
ts.get_stock_basics() 一次性返回全市场的基础字段(市盈率、流通股本、股东户数、上市时间、地域等),脚本把它落成 MySQL 表 bases 与本地 bases.csv,之后的筛选都在这个本地快照上做。这意味着它的时效性取决于你多久刷新一次这张表,而不是取决于 Tushare 的实时性。涨停池数据是实时的吗?
if_exists='fail' 的落库方式说明作者的用法是「每天抓一次」——想高频刷新需要自己改写入策略。回测结果能信吗?
backtest/ 只有 5 个教学示例文件;数据路径硬编码为作者本机绝对路径;只有一个 setcommission 调用、没有滑点模型、没有样本外划分、没有基准对比;ma_line_backtest.py 的数据文件在注释里写的是「可以公众号后台留言获取」。也就是说这个目录既不能直接用来评估策略,也不具备可复现的数据基础。有没有未来函数问题?
datahub/ 中用 Tushare 快照实现)时,要确认快照的时间口径;②recordMyChoice.py 这类「记录选股后收益」的脚本天然是样本外的,反而是四条链路里可信度最高的。要严格判断需要按策略逐条审计,本站没有做。