3. 核心字段解析

逐笔成交数据是行情数据中最细粒度的成交记录,每一条记录对应交易所撮合引擎完成的一次成交。要正确使用这类数据,必须先弄清五个基础字段:成交时间、成交价格、成交数量、成交金额、买卖方向。它们看似简单,但在实际数据中,单位不统一、精度不一致、方向标识混乱、异常值混入等问题非常普遍。本节围绕这五个字段逐一说明含义、单位、精度,并给出常见异常值的识别与处理办法。

成交时间:精度决定用途

成交时间表示该笔成交在交易所撮合系统中被确认的时刻。不同数据源给出的时间精度差异很大:有的只到秒(如 09:30:05),有的到毫秒(09:30:05.123),有的到微秒甚至纳秒。精度直接决定用途——秒级时间只能做粗粒度的分时统计,毫秒级才能支撑高频策略中的事件排序和延迟分析。

处理成交时间时要注意三点。第一,确认时间戳的时区与基准,国内A股行情通常为北京时间,且部分数据源的时间是交易所撮合时间而非本地接收时间,两者可能相差数十毫秒。第二,同一毫秒内可能有多笔成交,若数据源未提供序号字段,仅靠时间无法唯一排序,需要结合成交编号或原始行号。第三,注意集合竞价时段的时间归属,开盘集合竞价的成交常被标记在 09:25:00,收盘集合竞价标记在 14:57:00 至 15:00:00 之间,统计连续竞价指标时应将其剔除或单独处理。

成交价格与成交数量:单位与精度

成交价格是该笔成交的每股价格,单位为元。A股价格最小变动单位为 0.01 元,但部分数据源以“分”为单位存储整数(如 1234 表示 12.34 元),也有数据源以浮点数存储。读取时必须先确认单位,否则会出现价格放大或缩小 100 倍的严重错误。精度方面,价格字段应保留两位小数,若原始数据出现三位以上小数,通常是数据源换算或浮点误差所致,应做四舍五入或截断处理并记录。

成交数量是该笔成交的股数,单位为股。A股买入以 100 股为一手,但卖出可以不足 100 股(零股),因此成交数量不一定是 100 的整数倍。部分数据源以“手”为单位,读取时需乘以 100 换算为股。数量字段应为正整数,出现 0、负数或小数时即为异常。

成交金额等于成交价格乘以成交数量,单位为元。它本可由前两个字段计算得出,但很多数据源直接提供该字段,用于校验。校验方法是:成交金额 ≈ 成交价格 × 成交数量,允许因价格精度截断产生的小额误差(通常不超过 0.01 元乘以数量级)。若偏差明显,说明价格或数量字段存在单位错误或数据损坏。

买卖方向:参照系必须先定义

买卖方向标识该笔成交是主动买入还是主动卖出,通常以 B(Buy)、S(Sell)或 1、2 等编码表示。这里的关键是参照系:方向指的是“主动方”的方向,即成交时以买方报价成交还是以卖方报价成交。若数据源未明确说明,不能想当然地认为 B 就是买方发起。部分数据源用 0 表示未知方向(如集合竞价成交),这类记录在统计主动买卖量时应单独归类,不能强行归入买或卖。

常见异常包括:方向字段为空、出现未定义编码、同一笔成交方向与价格变动方向矛盾(如标记为主动买入但成交价低于买一价)。处理时应建立编码映射表,将原始编码统一转换为“主动买 / 主动卖 / 未知”三类,并对矛盾记录打标而非直接删除,以便后续核查。

逐笔成交五字段:含义、单位、精度与校验关系 成交时间 单位:时:分:秒(.毫秒) 精度:秒 / 毫秒 / 微秒 用途:排序、延迟分析 成交价格 单位:元(或分) 精度:0.01 元 注意:分/元换算 成交数量 单位:股(或手) 精度:整数 注意:零股、手×100 成交金额 单位:元 精度:0.01 元 用途:校验价格×数量 买卖方向 编码:B/S 或 1/2 参照:主动方方向 注意:未知方向单列 金额校验 成交金额 ≈ 成交价格 × 成交数量 常见异常值与处理策略 价格异常 单位错(分/元)→ 换算 小数超2位 → 四舍五入 数量异常 0/负数/小数 → 标记剔除 手单位 → ×100 换算 金额偏差 超容差 → 回查价格/数量 记录偏差值供审计 方向异常 空/未定义 → 归“未知” 与价格矛盾 → 打标核查 处理原则:先统一单位与编码 → 再做字段间交叉校验 → 异常记录打标保留,不静默删除 时间排序需结合成交编号;集合竞价成交单独归类;方向统计区分主动买、主动卖与未知

异常值处理的实际做法

面对上述字段,建议按“先统一、再校验、后打标”的顺序处理。第一步统一单位与编码:建立一张字段映射表,明确每个数据源的价格单位(元或分)、数量单位(股或手)、方向编码含义,并在读取阶段一次性转换。第二步做字段间交叉校验,重点是金额校验和方向与价格的逻辑校验。第三步对异常记录打标保留,而不是直接删除,因为删除会改变成交量统计口径,打标则便于追溯。

下面是一段示例性的校验代码,演示如何对单条记录做单位换算与金额校验(示例参数为合理假设,非实测数据):

# 假设原始记录:价格以分存储,数量以手存储,方向编码 1=主动买 2=主动卖 0=未知
raw = {"time": "09:30:05.123", "price": 1234, "volume": 3, "amount": 370200, "side": 1}

price = raw["price"] / 100.0          # 分 -> 元,得 12.34
volume = raw["volume"] * 100          # 手 -> 股,得 300
amount = raw["amount"] / 100.0        # 若金额也以分存储,换算为元

calc = round(price * volume, 2)       # 12.34 * 300 = 3702.00
diff = abs(calc - amount)
if diff > 0.01 * volume / 100:        # 容差按数量级设定
    flag = "金额偏差"
else:
    flag = "正常"

side_map = {1: "主动买", 2: "主动卖", 0: "未知"}
print(price, volume, calc, side_map.get(raw["side"], "未定义"), flag)

这段代码的关键不在语法,而在三个判断:单位换算是否与数据源说明一致、容差阈值是否合理、未定义方向是否被显式归类。实际工程中,容差通常设为“价格最小变动单位乘以数量”的量级,过严会把正常的精度截断误判为异常,过松则漏掉真正的单位错误。

字段整理时的记录要点

在编写代码字典时,每个字段至少应记录:字段名、中文含义、数据类型、单位、精度、取值范围、是否可空、异常判定规则、与其他字段的校验关系。以买卖方向为例,字典中应写明“编码 1 表示主动买,2 表示主动卖,0 表示未知,参照系为主动方方向”,而不是只写“买卖方向”。以成交金额为例,应写明“单位元,精度 0.01,应约等于价格乘数量,偏差超过容差时标记”。把这些规则固化到字典中,后续换数据源或多人协作时,才能避免同一字段被不同理解反复踩坑。

成交时间是排序的基础,但同毫秒多笔成交必须结合成交编号;价格和数量的单位错误往往表现为金额校验失败,因此金额校验是发现单位问题最有效的手段。
不要因为方向字段出现未知编码就整条丢弃,也不要将未知方向强行归入主动买或主动卖,否则主动买卖量统计会出现系统性偏差。