4. 数据采集与预处理图解
竞价买卖申报不平衡分析的质量,首先取决于数据底座的可靠性。本节围绕一条完整的数据处理链路展开:从交易接口拉取原始申报快照,到清洗异常值、对齐时间戳,最终构建可直接用于不平衡度计算的分析数据集。这条链路上的每一步都会影响后续指标的可信度,因此需要明确每个环节的输入、处理规则与输出形态。
一、从交易接口获取申报数据
集中竞价场景下,申报数据通常通过交易所或行情商的接口以快照(Snapshot)或逐笔(Tick)形式下发。以常见的 Level-2 行情快照为例,每个快照包含时间戳、证券代码、最新价、成交量、委托买入总量、委托卖出总量、买一至买十档价格与数量等字段。对于申报不平衡分析,我们最关心的是委买总量、委卖总量以及各档位的挂单分布。
实际采集时需要注意三个工程细节。第一,接口通常有频率限制,例如每 3 秒一个快照,采集程序应按接口约定节流,避免被限流或封禁。第二,快照是"截面数据",同一时间点只反映当前挂单状态,若要做申报增量分析,需要保存连续快照并做差分。第三,字段命名在不同数据源间不一致,例如委买总量可能叫 total_bid_vol、bid_volume 或 BP1 累加值,采集层应统一映射到标准字段名。
下面是一段示意性的采集伪代码,展示按标准字段落库的基本结构(参数为示例假设):
# 示例:快照采集与标准字段映射(伪代码)
SNAPSHOT_INTERVAL = 3 # 秒,示例假设
FIELDS_MAP = {
"total_bid_vol": "委买总量",
"total_ask_vol": "委卖总量",
"bid_px_1": "买一价",
"ask_px_1": "卖一价",
}
def fetch_snapshot(symbol):
raw = api.get_snapshot(symbol) # 调用交易接口
record = {std: raw.get(src) for src, std in FIELDS_MAP.items()}
record["symbol"] = symbol
record["ts_raw"] = raw["timestamp"] # 原始时间戳,待对齐
return record
while trading:
db.insert(fetch_snapshot("600000"))
sleep(SNAPSHOT_INTERVAL)
采集完成后,原始表通常保留全部字段与原始时间戳,作为"不可变原始层",后续清洗与对齐都在其副本上进行,保证可追溯。
二、清洗异常值
原始申报数据中常见的异常包括:委买或委卖总量为负、为零但价格非零、单笔快照量级突变(如突然放大百倍)、时间戳重复或倒序、字段缺失。清洗的目标不是"删掉不好看的数据",而是识别并标记这些记录,避免它们污染不平衡度指标。
推荐采用"规则过滤 + 统计标记"两层策略。规则层处理确定性错误:总量小于零直接置空;买卖总量同时为零视为无申报状态,保留但标记 no_quote;时间戳重复保留首条。统计层处理量级异常:对委买总量序列计算滚动中位数与绝对偏差(MAD),当某点偏离超过阈值(例如 5 倍 MAD)时标记为疑似异常,交由人工复核或按前后值插补。
clean_flag 与 clean_reason,便于回溯每一条被处理记录的原因。举例来说,若某快照委买总量为 120 万手,而前后 10 个快照均在 1.2 万手附近,则该点偏离约 100 倍,明显超出正常波动,应标记为异常而非直接参与计算。若确认是接口字段错位(如把成交量写入了委买量),则整段数据需重新采集。
三、对齐时间戳
不同数据源的时间戳精度和时区可能不同:交易所快照可能是毫秒级本地时间,而另一些接口给的是秒级 UTC 时间。若直接按字符串拼接,会出现同一时刻的数据被错位对齐,导致不平衡度在时间轴上"抖动"。
对齐分两步。第一步统一时区与精度:全部转换为同一时区(如北京时间),并统一到毫秒或秒。第二步按分析粒度重采样:若分析目标是分钟级不平衡度,则将快照按分钟分桶,取每桶最后一个快照作为该分钟的代表值(前向填充),或对桶内快照求均值。选择哪种取决于分析目的——研究挂单存量用末值,研究申报活跃度用均值。
对齐后应做一致性校验:检查时间序列是否严格递增、是否存在长时间空洞(如超过 30 秒无快照,可能为停牌或采集中断),并对空洞区间做显式标记,而不是让插值悄悄填平。
四、构建分析数据集
完成清洗与对齐后,构建面向分析的数据集。核心字段包括:证券代码、对齐后时间戳、委买总量、委卖总量,以及派生指标申报不平衡度。常用定义为:
imbalance = (bid_vol - ask_vol) / (bid_vol + ask_vol)
该指标取值在 [-1, 1] 之间,正值表示买方挂单占优,负值表示卖方占优,接近 0 表示相对均衡。分母为零时(双方均无申报)应置为空值而非 0,避免把"无数据"误读为"均衡"。
数据集还应包含质量字段:clean_flag、gap_flag、snapshot_count(该时间桶内快照数),使分析时可按质量分层过滤。最终输出一张宽表,一行对应一个"证券 × 时间桶",供后续统计与可视化直接使用。
五、质量校验与常见问题
数据集构建完成后,建议做三项快速校验。其一,抽样核对:随机抽取若干时间桶,回到原始快照手工核对委买委卖总量与不平衡度,确认映射与计算无误。其二,分布检查:绘制不平衡度直方图,正常交易日应集中在 0 附近并呈近似对称分布;若出现大量 ±1 的极端值,往往说明分母过小或清洗不彻底。其三,空洞统计:统计 gap_flag=1 的比例,若超过 5%,需排查采集中断或接口限流问题。
至此,一条从接口到分析数据集的链路闭合:采集保证字段完整与可追溯,清洗保证异常被识别而非被掩盖,对齐保证时间轴一致,数据集则把质量信息与派生指标一并交付。后续所有不平衡度的统计、分组与可视化,都应基于这张带有质量标记的分析宽表展开,而不是回到原始快照临时计算。