一、数据获取与预处理
1. 获取当日涨停股票清单
使用AKShare获取当日涨停股票基础数据,包含股票代码、名称、涨停价等核心字段:
import akshare as ak
import pandas as pd
获取当日涨停板数据(假设当前日期为2025-05-01)
df_limit = ak.stock_zt_pool_em(date=“20250501”) # :ml-citation{ref=“4” data=“citationList”}
df_limit = df_limit[[“代码”, “名称”, “最新价”, “涨停价”, “封单金额”, “首次封板时间”, “换手率”, “流通市值”]]
df_limit.columns = [“code”, “name”, “price”, “limit_price”, “order_amount”, “limit_time”, “turnover”, “circ_mv”]
2. 补充历史数据
通过Tushare获取近5日涨停次数和板块关联性数据:
import tushare as ts
ts.set_token(‘your_token’)
pro = ts.pro_api()
获取近5日涨停次数
hist_data = pro.limit_list(start_date=“20250426”, end_date=“20250501”)
hist_count = hist_data.groupby(“ts_code”)[“trade_date”].count().reset_index(name=“limit_count”)
合并数据
df_limit = pd.merge(df_limit, hist_count, left_on=“code”, right_on=“ts_code”, how=“left”)
二、评估维度与权重分配
构建6个核心指标评估涨停质量,权重分配如下:
指标 权重 说明 数据来源
封单强度 25% 封单金额/流通市值(比值越大强度越高) AKShare
涨停时间 20% 首次封板时间(越早得分越高) AKShare
换手率 15% 换手率越低表明筹码稳定性越好 AKShare
流通市值 15% 市值越小越容易获资金关注(小盘股优先) AKShare
历史连板次数 15% 近5日涨停次数(次数越多风险越高) Tushare
板块效应 10% 同板块涨停股数量(数量越多协同效应越强) Tushare
三、指标计算与归一化
1. 封单强度计算
封单强度 = 封单金额 / 流通市值
df_limit[“order_strength”] = df_limit[“order_amount”] / df_limit[“circ_mv”]
df_limit[“order_score”] = (df_limit[“order_strength”] / df_limit[“order_strength”].max()) * 25 # 归一化到25分
2. 涨停时间转换
将时间转为分钟数(如09:35→575分钟)
df_limit[“limit_minute”] = df_limit[“limit_time”].apply(
lambda x: int(x.split(“:”)[0])60 + int(x.split(“:”)[1])
)
df_limit[“time_score”] = (1 - df_limit[“limit_minute”]/570) * 20 # 09:30开盘,570=960+30
3. 其他指标归一化
换手率(越低越好)
df_limit[“turnover_score”] = (1 - df_limit[“turnover”]/df_limit[“turnover”].max()) * 15
流通市值(越小越好)
df_limit[“circ_mv_score”] = (1 - df_limit[“circ_mv”]/df_limit[“circ_mv”].max()) * 15
历史连板次数(反向指标)
df_limit[“history_score”] = (1 - df_limit[“limit_count”]/df_limit[“limit_count”].max()) * 15
板块效应(获取同板块涨停数量)
sector_count = df_limit.groupby(“sector”)[“code”].count().reset_index(name=“sector_count”)
df_limit = pd.merge(df_limit, sector_count, on=“sector”)
df_limit[“sector_score”] = (df_limit[“sector_count”] / df_limit[“sector_count”].max()) * 10
四、综合评分输出
1. 总分计算
df_limit[“total_score”] = (
df_limit[“order_score”] + df_limit[“time_score”] +
df_limit[“turnover_score”] + df_limit[“circ_mv_score”] +
df_limit[“history_score”] + df_limit[“sector_score”]
)
df_limit = df_limit.sort_values(“total_score”, ascending=False)
2. 结果展示
输出TOP10涨停股评分
print(df_limit[[“code”, “name”, “total_score”]].head(10))
可视化评分分布(Matplotlib)
import matplotlib.pyplot as plt
plt.figure(figsize=(10,6))
plt.barh(df_limit[“name”][:10], df_limit[“total_score”][:10])
plt.title(“今日涨停股质量评分TOP10”)
plt.xlabel(“综合得分”)
plt.show()
关键实现逻辑
封单强度权重最高:反映资金封板决心,通过封单金额/流通市值量化资金相对投入规模;
时间维度精细化:将首次封板时间转换为分钟数,早盘涨停股得分更高;
动态板块效应:通过统计同板块涨停数量捕捉热点联动性;
历史表现反向指标:连续涨停次数过多可能预示风险,需降低权重。
注意事项
数据清洗:需过滤ST股(涨停幅度5%)及新股首日数据;
实时更新:盘中封单金额会动态变化,建议结合定时任务更新数据;
阈值调整:可根据市场环境调整权重分配(如牛市提高板块效应权重)。