4. 核心字段详解(二)
在逐笔成交数据中,价格和数量回答的是“成交了多少”,而买卖方向、成交编号、委托编号等交易标识字段回答的是“谁在成交、成交属于哪一笔委托、这笔成交与前后成交是什么关系”。这些字段本身数值不大,却构成了逐笔数据从“孤立记录”走向“可关联事件流”的骨架。理解它们的编码方式与关联规则,是后续做委托生命周期还原、大单拆分识别、主力行为分析的前提。
一、买卖方向字段:先明确参照系,再谈含义
逐笔成交中的买卖方向(常见字段名为 BSFlag、Side、TradeBSFlag 等)表示主动成交方的方向,而不是挂单方的方向。其判定依据是:成交时买方报价不低于卖方报价,若成交由买方主动吃单形成,则方向记为买(B);若由卖方主动砸单形成,则记为卖(S)。这一点必须先讲清楚,因为很多初学者会把它误解为“这笔成交里买方是谁”,从而在统计主动买卖净额时把符号搞反。
不同数据源的编码并不统一。上交所 Level-2 逐笔成交常用 B/S 字符;部分券商落地文件用 1/2 或 0/1 表示;还有的数据源用 +1/-1 表示买卖方向,用 0 表示未知或集合竞价成交。工程上必须做一次显式映射,不能依赖“看起来像”的默认值。例如把字符型统一转换为枚举:
# 示例:方向字段标准化(示例映射,实际以数据源文档为准)
DIR_MAP = {
"B": "BUY", "S": "SELL",
"1": "BUY", "2": "SELL",
"0": "UNKNOWN"
}
def normalize_side(raw):
key = str(raw).strip().upper()
return DIR_MAP.get(key, "UNKNOWN")
需要特别注意的是,集合竞价阶段(开盘、收盘)产生的成交往往没有明确的主动方,方向字段可能为空、为 0 或直接标记为中性。若在统计中把它们强行归入买或卖,会系统性污染主动买卖差额。合理做法是单独打上“竞价成交”标签,在连续竞价分析中剔除。
二、成交编号与委托编号:两类不同粒度的标识
成交编号(TradeIndex、TradeID、成交序号)标识的是一笔成交事件,通常在同一交易日内按时间顺序递增,具有唯一性。它是最细粒度的“事件身份证”,用于去重、排序和定位。委托编号(OrderID、OrderNo、委托序号)标识的是一笔委托订单,同一笔委托可能对应多笔成交——这正是大单被拆分成多笔撮合的直接体现。
两者的关系可以概括为:一个委托编号对应 1 到 N 个成交编号,而一个成交编号只对应一个买方委托编号和一个卖方委托编号。因此逐笔成交记录中通常同时携带买方委托号和卖方委托号(如 BidOrderID、AskOrderID),通过它们才能把成交事件挂回到具体的委托上。若数据源只提供单一委托号字段,需要先确认它记录的是主动方委托号还是被动方委托号,否则关联方向会错位。
三、关联关系的还原逻辑
把上述字段串起来,就能还原出委托与成交的树状结构。以示例数据说明(以下数值为教学构造的示例,非实测):某日 10:00:03,委托号 880021 的买单先后与委托号 990105、990106 两笔卖单成交,成交编号分别为 5001、5002。此时可观察到:同一买方委托号出现两次,成交编号各不相同,方向均为 B。这说明该买单被分两笔撮合完成,属于典型的拆单成交。
还原时建议按以下顺序处理:先按成交编号排序保证事件时序;再以(买方委托号,卖方委托号)为键建立成交到委托的映射;最后按委托号聚合,统计每笔委托的成交笔数、累计成交量与成交均价。若累计成交量小于委托原始数量,说明该委托尚未完全成交或已撤单,需要结合委托表进一步判断。
四、实操中的常见坑与校验方法
第一类是编号跨日重置。成交编号和委托编号通常只在单个交易日内唯一,跨日直接拼接会导致键冲突。落库时应以“交易日 + 编号”作为联合主键,或在读取时先按日期分区。
第二类是编号类型不一致。有的数据源委托号是字符串(可能带前导零),有的是整型,混用会导致 00123 与 123 被当成两个不同委托。读取阶段应统一为字符串并保留原始长度,避免数值化丢位。
第三类是方向与委托号不匹配。若某笔成交方向为 B,但买方委托号为空或与卖方委托号相同,说明数据存在缺失或错位,应标记为异常记录而非直接参与统计。可以写一个轻量校验:
# 示例:逐笔成交基础校验(示例规则)
def check_trade(row):
issues = []
if not row.get("trade_id"):
issues.append("成交编号缺失")
if row.get("side") not in ("BUY", "SELL", "UNKNOWN"):
issues.append("方向编码异常")
if row.get("side") == "BUY" and not row.get("bid_order_id"):
issues.append("买方委托号缺失")
if row.get("bid_order_id") == row.get("ask_order_id"):
issues.append("买卖委托号相同")
return issues
校验通过后,再进入聚合环节。一个可复用的判断依据是:对同一委托号,累计成交量不应超过其委托量;若超过,说明委托号被复用或数据重复,需要回查原始文件。这类一致性检查能在分析前拦下大部分脏数据,比事后修正结论要省力得多。
把方向、成交编号、委托编号三者放在一起看,逐笔成交就不再是一张平铺的记录表,而是一棵可以向上追溯到委托、向下拆分到单笔撮合的事件树。后续无论是识别大单拆分、统计主动买卖力量,还是还原撤单行为,都建立在这套标识与关联关系之上。