AlphaFeed Blog

如何用 Python 按市值 / 流通市值筛选股票?(小市值策略数据准备)

选股扫描 · 代码验证于 2026-09-04

如何用 Python 按市值 / 流通市值筛选股票?(小市值策略数据准备)

一句话回答: 市值 = 最新价 × 总股本,流通市值 = 最新价 × 流通股本。AlphaFeed 的标的元数据接口直接提供 total_shares(总股本)和 float_shares(流通股本),配合实时行情的 last_price,几行 Python 就能给全市场算市值、做分层和小市值选股。

为什么市值这么关键

市值是最重要的横截面因子之一:

问题是:很多免费数据源只给行情,不给股本,或者股本字段口径混乱、需要东拼西凑。而市值必须用实时价 × 股本动态计算——昨天的市值不等于今天的。

第一步:拿到股本数据(标的元数据)

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 线,并考虑停牌、涨停无法买入等约束。

和其他数据源比

能力免费聚合库TushareAlphaFeed
总股本/流通股本字段零散、口径不一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。

相关链接:


免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。小市值策略波动与风险较高,历史数据不代表未来表现。