3. 行情数据构建与板块指数处理
板块融资余额与行情对照分析的第一步,不是画图,而是把“板块行情”整理成一张干净、可对齐的面板数据。融资余额通常按交易日披露,板块行情则来自行情接口或数据文件,两者在字段口径、日期格式、复权方式上往往并不一致。如果直接合并,很容易出现日期错位、涨跌幅重复计算、成交额单位混乱等问题,最终让后续的相关性分析失真。本节围绕板块行情数据的构成、关键字段的处理方式,以及面板数据的构建与对齐展开。
一、板块行情数据由哪些字段构成
一个可用的板块日行情记录,至少应包含以下核心字段:
- 交易日期(trade_date):行情所属交易日,是后续与融资余额对齐的主键。
- 板块代码与板块名称(sector_code / sector_name):用于唯一标识板块,避免同名板块混淆。
- 指数收盘价(close):板块指数的收盘点位,是计算区间收益的基础。
- 涨跌幅(pct_chg):当日相对前一交易日的百分比变化,通常以百分数表示。
- 成交额(amount):当日板块成分股成交金额合计,反映交易活跃度。
- 可选字段:开盘价、最高价、最低价、成交量、换手率等,视分析需要保留。
需要特别注意的是,不同数据源对“板块指数”的定义不同:有的是按成分股自由流通市值加权,有的是等权,有的直接采用第三方编制的行业指数。口径一旦确定,整个分析过程应保持一致,不能中途混用。
二、关键字段的处理要点
1. 收盘价与复权。板块指数一般不像个股那样存在分红送转导致的除权缺口,但若使用的是自行合成的板块指数,则需明确是否做了复权处理。对于第三方行业指数,直接使用其发布的收盘点位即可。若分析区间跨越指数编制方法调整,应在数据说明中标注,避免把方法调整误读为行情变化。
2. 涨跌幅的两种来源。涨跌幅可以直接取行情接口返回的 pct_chg 字段,也可以由收盘价自行计算:pct_chg = (close_t / close_{t-1} - 1) × 100。两种方式在正常情况下应基本一致,但遇到停牌、指数调整或数据缺失时可能产生差异。建议以接口字段为主,并用自算值做交叉校验,发现偏差超过阈值(例如 0.5 个百分点)时回查原始数据。
3. 成交额的单位与缺失。成交额常见单位为元、万元或亿元,合并前必须统一。若某日成交额缺失,不宜简单填 0,因为 0 会被误读为“无成交”,更合理的做法是标记为缺失值并在分析时剔除或前向填充(需注明处理方式)。
4. 日期格式统一。行情数据可能是 2024-01-05、20240105 或带时间戳的格式,融资余额数据又可能是另一种格式。统一转换为 YYYY-MM-DD 的日期类型,是后续对齐的前提。
三、面板数据的构建与对齐
所谓面板数据,是指“板块 × 交易日”的二维结构:每一行是一个板块在某一天的一条记录,列则包含行情字段与融资余额字段。构建过程可以概括为三步:先分别整理行情表和融资余额表,再按“板块代码 + 交易日期”做外连接或内连接,最后处理连接产生的缺失与重复。
连接方式的选择取决于分析目的。若研究“融资余额变化与行情涨跌的同期关系”,应使用内连接,只保留两边都存在的交易日;若需要观察融资余额在行情缺失日的表现,可用左连接并以行情表为主表。无论哪种方式,都要检查连接后的行数是否合理——行数异常膨胀通常意味着主键存在重复。
对齐时还有一个容易被忽视的问题:融资余额数据常以“前一交易日收盘后”的余额披露,而行情涨跌幅是当日盘中变化。因此在做同期对照时,应明确融资余额对应的是 T 日收盘后的余额,还是 T-1 日收盘后的余额,并在全文保持同一约定。这一约定直接影响后续相关性符号的解读。
四、一个可执行的处理示例
下面以 Python 的 pandas 为例,给出一个最小可运行的处理流程。假设已从数据源得到两个 DataFrame:df_quote 与 df_margin。
import pandas as pd
# 1. 统一日期格式
df_quote["trade_date"] = pd.to_datetime(df_quote["trade_date"])
df_margin["trade_date"] = pd.to_datetime(df_margin["trade_date"])
# 2. 统一成交额单位(假设原始为万元,转为亿元)
df_quote["amount"] = df_quote["amount"] / 10000
# 3. 校验涨跌幅:接口值与自算值对比
df_quote = df_quote.sort_values(["sector_code", "trade_date"])
df_quote["pct_calc"] = df_quote.groupby("sector_code")["close"].pct_change() * 100
df_quote["diff"] = (df_quote["pct_chg"] - df_quote["pct_calc"]).abs()
print(df_quote[df_quote["diff"] > 0.5][["trade_date", "sector_code", "pct_chg", "pct_calc"]])
# 4. 按主键对齐
panel = pd.merge(
df_quote[["trade_date", "sector_code", "close", "pct_chg", "amount"]],
df_margin[["trade_date", "sector_code", "fin_balance"]],
on=["trade_date", "sector_code"],
how="inner"
)
# 5. 检查重复与缺失
print(panel.duplicated(subset=["trade_date", "sector_code"]).sum())
print(panel.isna().sum())
这段代码的关键不在语法,而在于每一步都在做“口径校验”:日期是否可比较、单位是否一致、涨跌幅是否可信、主键是否唯一、缺失是否在可接受范围。只有这些检查通过,面板数据才具备进入下一步分析的条件。
五、对齐后的质量检查
完成合并后,建议至少做三项检查。第一,行数检查:合并后的行数应等于两表主键交集(内连接)或行情表行数(左连接),若明显偏多,说明主键有重复。第二,日期连续性检查:按板块分组后,交易日序列应与交易日历一致,缺失的交易日需确认是停牌、数据缺失还是节假日。第三,数值合理性检查:涨跌幅是否出现异常极值(如超过 ±20%),成交额是否出现突增突降,融资余额是否出现非经济含义的跳变。这些异常往往是数据拼接错误或单位错误的信号。
data_source 或 update_time,记录每条记录的来源与更新时间。当后续发现某段区间的数据异常时,可以快速定位是哪个数据源、哪次更新引入的问题。至此,板块行情数据已经从原始字段整理为结构清晰、口径一致、可与融资余额逐日对照的面板数据。后续的融资余额变化计算、行情涨跌分组、相关性观察,都将建立在这张面板之上。数据构建阶段多花的时间,会在分析阶段以更少的返工和更可信的结论回报回来。