如何用 Python 按市值 / 流通市值筛选股票?(小市值策略数据准备)
如何用 Python 按市值 / 流通市值筛选股票?(小市值策略数据准备)
一句话回答: 市值 = 最新价 × 总股本,流通市值 = 最新价 × 流通股本。AlphaFeed 的标的元数据接口直接提供 total_shares(总股本)和 float_shares(流通股本),配合实时行情的 last_price,几行 Python 就能给全市场算市值、做分层和小市值选股。
为什么市值这么关键
市值是最重要的横截面因子之一:
- 小市值效应是 A 股经典(也高波动、高风险)的现象;
- 很多策略需要按市值分层(大/中/小盘分别对待);
- 剔除超大盘或超小盘、控制组合的市值暴露,都要先算出市值。
问题是:很多免费数据源只给行情,不给股本,或者股本字段口径混乱、需要东拼西凑。而市值必须用实时价 × 股本动态计算——昨天的市值不等于今天的。
第一步:拿到股本数据(标的元数据)
af.instruments 返回的 ext 里含总股本、流通股本、上市日期、涨跌停价等(实测字段):
from alphafeed import AlphaFeed
af = AlphaFeed() # 读取 ALPHAFEED_API_KEY
inst = af.instruments.get("600519.SH")
ext = inst["ext"]
print(ext["total_shares"], ext["float_shares"], ext["listing_date"])
# 1250081601.0 1250081601.0 2001-08-27
ext 里可用于市值/报价的关键字段:
| 字段 | 含义 |
|---|---|
total_shares | 总股本(股) |
float_shares | 流通股本(股) |
tick_size | 最小变动价位 |
limit_up / limit_down | 今日涨/跌停价 |
listing_date | 上市日期 |
第二步:全市场算市值
思路:全 A 快照拿 last_price,批量元数据拿股本,按 symbol 合并后相乘。
import pandas as pd
# 1. 全 A 实时价
q = af.quotes.get(universes="CN_Stock", to_dataframe=True)[["symbol", "last_price", "ext.name"]]
# 2. 批量股本(SDK 自动分批,默认每批 200)
insts = af.instruments.batch(q["symbol"].tolist(), show_progress=True)
shares = pd.DataFrame([
{"symbol": i["symbol"],
"total_shares": i.get("ext", {}).get("total_shares"),
"float_shares": i.get("ext", {}).get("float_shares")}
for i in insts
])
# 3. 合并并计算市值(单位:亿元)
m = q.merge(shares, on="symbol", how="inner").dropna(subset=["total_shares"])
m["total_mktcap"] = m["last_price"] * m["total_shares"] / 1e8
m["float_mktcap"] = m["last_price"] * m["float_shares"] / 1e8
print(m[["symbol", "ext.name", "last_price", "total_mktcap", "float_mktcap"]].head())
第三步:市值分层
按流通市值分成大/中/小盘:
def tier(cap):
if cap >= 1000: # ≥ 1000 亿
return "大盘"
if cap >= 100: # 100~1000 亿
return "中盘"
return "小盘" # < 100 亿
m["tier"] = m["float_mktcap"].apply(tier)
print(m["tier"].value_counts())
第四步:小市值选股(含必要过滤)
小市值策略最忌“踩雷”,务必叠加流动性、剔除 ST 与次新股等过滤:
# 结合成交额(需在 quotes 里保留 amount 字段)
q2 = af.quotes.get(universes="CN_Stock", to_dataframe=True)
q2 = q2.merge(shares, on="symbol", how="inner").dropna(subset=["float_shares"])
q2["float_mktcap"] = q2["last_price"] * q2["float_shares"] / 1e8
small = q2[
(q2["float_mktcap"] >= 20) # 流通市值 ≥ 20 亿,避免过度微盘
& (q2["float_mktcap"] <= 50) # ≤ 50 亿,聚焦小盘
& (q2["amount"] > 1e8) # 流动性
& (~q2["ext.name"].str.contains("ST", na=False)) # 剔除 ST
].sort_values("float_mktcap")
print(f"小市值候选: {len(small)} 只")
print(small[["symbol", "ext.name", "last_price", "float_mktcap", "amount"]].head(20))
剔除次新股可结合
listing_date(上市不足 N 天的排除)。
第五步:等权构建小市值组合
topN = small.head(20).copy()
topN["weight"] = 1 / len(topN)
print(topN[["symbol", "ext.name", "float_mktcap", "weight"]].to_string(index=False))
定期(如每月)重新扫描、再平衡,就是一个最朴素的小市值轮动框架。回测时记得用前复权 K 线,并考虑停牌、涨停无法买入等约束。
和其他数据源比
| 能力 | 免费聚合库 | Tushare | AlphaFeed |
|---|---|---|---|
| 总股本/流通股本 | 字段零散、口径不一 | daily_basic 等接口(需积分) | instruments.ext 直接给 |
| 实时价算动态市值 | 实时性弱 | 实时有限 | 快照 last_price |
| 全市场批量 | 易被封 | 频次受限 | instruments.batch 自动分批 |
常见问题(FAQ)
Q:total_shares 单位是什么?
A:股。总市值 = last_price × total_shares,除以 1e8 得“亿元”。
Q:总市值和流通市值用哪个选股?
A:小市值/流动性相关一般看流通市值(float_shares);衡量公司整体规模看总市值。
Q:市值会变,多久算一次? A:市值随价格实时变化,选股时用当日快照现算即可;不要缓存历史市值当今天用。
Q:需要付费吗?
A:全市场 universes 查询与大批量 instruments 需 Starter 及以上;少量标的可用免费额度。
小结
“按市值选股”的前提是能稳定拿到股本 + 实时价。AlphaFeed 把总股本、流通股本放进标的元数据,配合全市场快照,市值计算、分层、小市值选股都变成几行 pandas。
相关链接:
- AlphaFeed 官网:https://alphafeed.org/
- Python SDK 快速开始:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。小市值策略波动与风险较高,历史数据不代表未来表现。