1. 课程导入与数据准备
在讨论“板块上涨家数”和“市场宽度”之前,需要先明确一个前提:这两个指标都不是行情软件里现成的单一数字,而是由“板块成分股列表”和“每只成分股的日行情”两部分数据加工出来的派生指标。数据准备做得是否扎实,直接决定了后续宽度曲线、宽度背离、板块轮动判断是否可信。本章不急于计算指标,而是把分析目标、数据源选择、成分股与行情获取、清洗校验这条链路走通,最终得到一个可以直接进入计算环节的干净数据集。
一、先定义清楚要回答的问题
“板块上涨家数”通常指某一板块内当日收盘价高于前一交易日收盘价的成分股数量;“市场宽度”则是一个更宽的概念,常用上涨家数占比、涨跌家数比、站上某条均线的成分股比例等来刻画。两者共同回答的核心问题是:指数的涨跌,是由少数权重股拉动的,还是由多数个股共同推动的?
因此本课程的分析目标可以拆成三层:第一层是单日横截面,即某板块当日上涨家数、下跌家数、平盘家数及上涨占比;第二层是时间序列,即把上述统计量按交易日滚动,形成宽度曲线;第三层是结构对比,即把板块宽度与板块指数走势、与全市场宽度做对照,识别“指数涨但宽度缩”这类背离信号。目标一旦明确,数据需求就随之确定:需要板块成分股清单、每只成分股的日线收盘价,以及交易日历用于对齐。
二、常用数据源及其取舍
实际工作中常见三类数据源,各有适用场景:
- 行情软件导出(如同花顺、通达信、东方财富的板块成分与日线导出):上手快、字段直观,适合快速验证想法;缺点是批量导出繁琐、复权口径与字段命名不统一,长期维护成本高。
- 交易所与官方披露数据:权威性最好,适合做成分股归属与停复牌的最终校验;但接口分散、更新节奏固定,不适合高频迭代。
- Python 财经接口(如 AkShare、Tushare 等):可编程批量拉取,便于把“成分股—日行情—交易日历”串成流水线,是本课程推荐的主路径;需注意接口的积分权限、频率限制与字段变更。
本课程采用“Python 接口为主、行情软件抽样核对为辅”的策略:批量数据走接口,关键日期抽几只股票与软件对照,既保证效率又保留可验证性。
三、成分股列表与日行情获取
以 AkShare 为例,板块成分股可通过板块名称接口获取,日行情通过历史行情接口按股票代码逐只拉取。下面是一段可直接改造使用的示例代码,参数与返回结果均为教学示例,实际运行时以接口当前返回为准。
import akshare as ak
import pandas as pd
# 1) 获取板块成分股(示例:某行业板块)
cons = ak.stock_board_industry_cons_em(symbol="半导体")
codes = cons["代码"].tolist()
# 2) 逐只拉取日线,只保留需要的字段
frames = []
for code in codes:
df = ak.stock_zh_a_hist(
symbol=code, period="daily",
start_date="20240101", end_date="20240630",
adjust="qfq" # 前复权,保证价格序列可比
)
df = df[["日期", "收盘", "成交量"]].copy()
df["代码"] = code
frames.append(df)
raw = pd.concat(frames, ignore_index=True)
raw["日期"] = pd.to_datetime(raw["日期"])
print(raw.shape, raw["代码"].nunique())
这里有两个容易被忽略的细节。其一是复权口径:计算“今日收盘是否高于昨日收盘”时,若中途发生除权除息而未复权,价格会出现向下跳空,被误判为下跌。统一使用前复权可以规避,但要注意前复权序列会随最新除权事件整体变化,因此每次重算都应重新拉取,而不是长期缓存旧复权价。其二是字段对齐:不同接口对“日期”“收盘”的命名不同,建议在拼接前统一重命名为固定列名,避免后续合并出错。
四、清洗与校验:让数据可计算
原始拼接结果通常存在缺失交易日、停牌空值、重复行和新股上市初期数据不足等问题。清洗的目标不是“删得干净”,而是“规则统一、可追溯”。建议按以下顺序处理:
- 去重:按“代码 + 日期”去重,保留最后一条,防止重复拉取造成家数虚增。
- 对齐交易日历:以交易日历为基准做透视,缺失的“代码—日期”组合说明当日停牌或无数据,先标记为缺失而非直接删除。
- 停牌处理:停牌日不参与“上涨/下跌”计数,也不计入分母,否则会人为压低上涨占比。可在透视后统计每日有效交易股票数,作为宽度计算的分母。
- 新股与退市处理:上市不足一定天数(如 20 个交易日)的股票在计算“站上均线比例”类宽度时剔除,避免样本不足导致比例失真。
- 异常值核查:单日涨跌幅超过合理阈值(如 ±21%,考虑不同板块涨跌幅限制)的记录应回查,确认是复权错误还是数据源错误。
清洗完成后,把长表透视为“日期 × 代码”的收盘价矩阵,再逐列做 pct_change() 得到日收益率矩阵,就可以按行统计上涨家数。这一步是后续所有宽度指标的共同入口,务必保证矩阵的行是交易日、列是成分股、单元格是可比价格。
上图把本章的链路压缩成一条可检查的路径:目标决定数据源,数据源产出成分股与行情,清洗校验把原始数据变成“日期 × 代码”的矩阵,矩阵再进入家数与占比计算。图中 06-04 这一行的示例说明了一个关键规则:停牌股票不计入分母,当日有效样本为 3 只,上涨 1 只,上涨占比为 33.3%,而不是按 4 只成分股计算出的 25%。这个分母口径必须在整条时间序列上保持一致,否则宽度曲线会在停牌密集期出现系统性偏差。
五、交付一份可复用的数据检查清单
为了让数据准备可复现,建议在每次更新数据后固定核对以下几项,形成一份简短的检查记录:
| 检查项 | 判断标准 | 不通过时的处理 |
|---|---|---|
| 成分股数量 | 与板块最新披露数量一致 | 重新拉取成分清单,核对调仓日期 |
| 日期覆盖 | 起止日期内交易日无整段缺失 | 补齐交易日历,定位缺失区间 |
| 复权口径 | 全部为前复权且同一拉取批次 | 整批重拉,禁止混用新旧复权价 |
| 停牌标记 | 缺失值已标记,未混入涨跌计数 | 透视后统计每日有效样本数 |
| 异常涨跌幅 | 超出阈值记录已逐条回查 | 修正数据源或剔除并记录原因 |
完成以上步骤后,你手里应当有一份按交易日排列、列名为股票代码、单元格为前复权收盘价的矩阵,以及一份每日有效样本数序列。前者用于计算涨跌方向,后者用于确定宽度指标的分母。数据准备阶段多花的时间,会在后续宽度背离判断中直接转化为结论的可靠性——因为宽度分析最怕的不是指标公式复杂,而是分母悄悄变了却没人发现。