一句话回答: 自建指数的本质是"给一篮子成分股按某种权重加权求和,再归一到一个基点"。用 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)
instruments 的 ext 字段(自建指数常用):
| 字段 | 含义 | 备注 |
|---|---|---|
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 等权的对比看清组合的结构。
参考
- AlphaFeed Python SDK 文档:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart

