如何用 Python 自建一个股票指数?

用户头像sh_*2176oo
2026-09-17 发布

一句话回答: 自建指数的本质是"给一篮子成分股按某种权重加权求和,再归一到一个基点"。用 AlphaFeed 的 instruments.batch 取每只票的流通股本klines.batch前复权收盘价,用「Σ(价格 × 流通股本)」做流通市值加权指数,或用等权方式做对比,几十行就能给你的自选股组合造一条专属指数。

为什么会有这个问题 / 传统做法的痛点

想跟踪一个自选股组合、行业篮子或策略持仓的整体走势时,直接看个股很乱,需要一条"合成指数"。但自己算常卡在:

  • 权重从哪来:市值加权要用流通股本,免费源往往拿不到干净的股本数据;
  • 复权不统一:成分股各自除权除息,不用复权价算出来的指数会有假跳空;
  • 成分对齐:不同票停牌/上市时间不同,日期不对齐会算错。

AlphaFeed 把股本(instruments.ext.float_shares)和前复权 K 线放在同一套接口里,口径一致、可复现。

分步骤解决(每步配可运行代码)

第 1 步:取成分股的流通股本

from alphafeed import AlphaFeed
import pandas as pd

af = AlphaFeed(api_key="your-api-key")  # 或 export ALPHAFEED_API_KEY 后 AlphaFeed()

symbols = ["600519.SH", "000001.SZ", "601398.SH", "600036.SH", "000858.SZ"]
insts = af.instruments.batch(symbols)      # 返回 list[dict]
float_shares = {}
for it in insts:
    ext = it.get("ext", {}) or {}
    float_shares[it["symbol"]] = float(ext.get("float_shares") or 0.0)
print(float_shares)

instrumentsext 字段(自建指数常用):

字段 含义 备注
float_shares 流通股本(股) 流通市值加权用它
total_shares 总股本(股) 总市值加权可用它
listing_date 上市日期 判断成分是否在样本期内
tick_size 最小变动价位

流通市值 = 价格 × 流通股本。指数只关心"相对变化",所以用哪种股本口径要和你的目的一致(跟踪流通盘用 float_shares)。

第 2 步:取前复权收盘价并对齐

bt = af.klines.batch(symbols, period="1d", count=250,
                     adjust="forward", to_dataframe=True)
closes = {}
for sym, df in bt.items():
    if df is None or df.empty:
        continue
    s = df.sort_values("trade_date").set_index("trade_date")["close"]
    closes[sym] = s
px = pd.DataFrame(closes).dropna()          # 对齐交易日,去掉任一停牌日

第 3 步:计算流通市值加权指数(并与等权对比)

def build_index(px, float_shares, base=1000.0):
    w = pd.Series({s: float_shares.get(s, 0.0) for s in px.columns})
    cap = (px * w).sum(axis=1)                       # 每日总流通市值
    cap_weighted = cap / cap.iloc[0] * base          # 归一到基点 base
    equal_weighted = (px / px.iloc[0]).mean(axis=1) * base
    return pd.DataFrame({"cap_weighted": cap_weighted,
                         "equal_weighted": equal_weighted})

idx = build_index(px, float_shares, base=1000.0)
print(idx.tail(3))
# 例如(基点=1000):
#             cap_weighted  equal_weighted
# 2026-09-11     969.78         923.50

两条指数的差异很有信息量:市值加权被大盘股主导(如工商银行流通盘极大),等权更能反映"平均个股"表现。上例里等权指数明显更低,说明样本期内小票整体弱于权重股。

关键坑与注意事项

  • 必须前复权:成分股要用 adjust="forward",否则除权日会在指数里制造假跳空。
  • 基点归一:指数只有相对意义,务必用第一天做分母归一到基点(如 1000),不同基点只影响绝对数值不影响形态。
  • 成分对齐dropna() 会丢掉任一成分停牌的交易日;成分很多时可考虑前值填充,但要注意停牌期用旧价可能失真。
  • 权重是否随时间变:本文用固定流通股本(近似)。严格的市值加权指数股本会随增发/回购变化,长周期要考虑用当期股本,否则会有偏差。
  • 别把它当官方指数:这是自定义篮子指数,用于跟踪你自己的组合/观察,不等于中证/沪深官方指数的编制方法(后者有分级靠档、自由流通调整等规则)。

常见问题(FAQ)

Q:流通市值加权和总市值加权用哪个?
A:跟踪"可交易盘"的表现用流通股本(float_shares);想反映公司整体规模用总股本(total_shares)。两者代码只差取哪个字段。

Q:为什么我的自建指数和某只权重股几乎一模一样?
A:因为市值加权下超大盘股权重过高,会主导指数。想看"平均个股"就用等权,或对权重做上限(capping)。

Q:能加入新股/剔除退市股做动态成分吗?
A:可以,但要按日期维护成分名单并处理进出场时点,属于指数编制的进阶话题;本文先给固定成分的最简版本。

Q:需要付费吗?
A:少量成分股的 K 线与 instruments 在免费额度内即可试跑;大篮子/全市场批量取数需 Starter 及以上,详见 AlphaFeed 定价页。

小结

自建指数不神秘:取成分股的复权价与股本 → 按权重加权求和 → 归一到基点。难点在数据口径——复权、股本、成分对齐。AlphaFeed 把这些放进同一套接口,让你几十行就能给任意自选股篮子造一条可复现的专属指数,并通过市值加权 vs 等权的对比看清组合的结构。

参考

评论