第二章 逐笔成交与Tick数据:数据结构的底层逻辑

做量化交易这些年,我越来越觉得——数据是交易的血液。而逐笔成交和Tick数据,就是最原始的血液样本。

很多人喜欢看K线,觉得那才是交易。但说实话,K线是加工过的信息。它把几万笔交易压缩成了四个价格。你想想看,中间丢失了多少细节?

我个人习惯,每天开盘前先看15分钟的逐笔成交。不是为了找交易机会,而是为了感受市场的「呼吸节奏」。这比任何指标都真实。

2.1 逐笔成交数据的结构

逐笔成交数据,说白了就是每一笔真实成交的记录。交易所撮合一次,就产生一条数据。

它的核心字段其实不多,但每个字段都藏着信息量:

字段名 含义 我的理解
时间戳 精确到毫秒或微秒 这是最容易被忽视的维度。毫秒级的差异,往往意味着不同的交易意图
成交价 该笔交易的撮合价格 注意:不是报价,是真实成交价
成交量 该笔交易的股数/手数 大单还是小单?这里能看出资金性质
成交额 成交价 × 成交量 有些交易所直接给,有些需要自己算
买卖方向 主动买还是主动卖 这是订单流分析的核心中的核心
成交编号 交易所生成的唯一ID 用来去重和排序,比时间戳更可靠

核心认知:逐笔成交数据是「结果」,不是「过程」。它告诉你发生了什么,但不直接告诉你为什么会发生。后者需要结合订单簿数据来分析。

我在项目中遇到过一个问题:某只股票突然放量拉升,逐笔成交显示全是主动买。但后来复盘发现,那些「主动买」其实是量化资金在对倒。怎么发现的?看成交编号的连续性——正常交易会有间隔,对倒的成交编号是连续的。

2.2 Tick数据的采集与清洗

Tick数据,很多人把它和逐笔成交混为一谈。其实不一样。

Tick数据是快照,它记录的是某个时间点上,市场状态的完整切片。包括最新价、买卖盘口、成交量、持仓量等。而逐笔成交是事件流,每成交一笔就产生一条。

嗯,这里要注意:不同交易所对Tick的定义不同。有的交易所1秒拍一张快照,有的500毫秒。你如果做高频策略,这个差异会直接影响你的回测精度。

2.2.1 数据采集的坑

我曾经自己搭过一套数据采集系统,踩过的坑可以写本书了。这里挑几个重点说:

  • 时间同步问题:交易所的时钟和你的服务器时钟可能有偏差。我建议用NTP协议同步,偏差控制在1毫秒以内。
  • 数据丢失:网络抖动会导致丢包。我习惯在采集端做本地缓存,每5秒批量上传一次。即使网络断了,数据也不会丢。
  • 重复数据:有些数据源会推送重复的Tick。一定要用成交编号或时间戳+价格+成交量的组合做去重。

避坑指南:我曾经因为没处理好时间同步,导致回测结果和实盘差了0.3秒。0.3秒在Tick级别交易里,就是天堂和地狱的区别。从那以后,我每套系统都会加一个时间校准模块。

2.2.2 数据清洗流程

数据清洗这件事,80%的时间花在20%的脏数据上。我的清洗流程是这样的:

  1. 格式校验:检查字段类型、长度、范围。比如价格不能为负,成交量不能为0。
  2. 时间排序:按时间戳升序排列。注意处理同一毫秒内的多条数据。
  3. 去重处理:基于成交编号或关键字段组合去重。
  4. 异常值过滤:价格超过当日涨跌停板、成交量超过正常范围等,标记出来人工复核。
  5. 缺失值填充:对于Tick数据,如果某秒没有快照,我一般用前向填充(forward fill)。

给你看一段我常用的清洗代码片段:

def clean_tick_data(df):
    """
    清洗Tick数据
    """
    # 1. 格式校验
    df = df[(df['price'] > 0) & (df['volume'] >= 0)]
    
    # 2. 时间排序
    df = df.sort_values('timestamp')
    
    # 3. 去重
    df = df.drop_duplicates(subset=['trade_id'])
    
    # 4. 异常值过滤
    df = df[df['price'] <= df['upper_limit']]
    df = df[df['price'] >= df['lower_limit']]
    
    # 5. 缺失值填充(前向填充)
    df = df.fillna(method='ffill')
    
    return df

小技巧:清洗后的数据,我习惯再跑一遍「完整性检查」。比如检查一天的数据条数是否在合理范围内。如果某天数据量突然少了30%,大概率是采集端出了问题。

2.3 逐笔成交与Tick的关系

这两者的关系,我用一张图来说明:

逐笔成交 vs Tick数据:关系与对比 逐笔成交(事件流) • 每笔成交产生一条记录 • 包含:时间、价格、量、方向 • 数据量:每天数万到数百万条 • 特点:实时性高,细节丰富 • 用途:订单流分析、动量捕捉 聚合 Tick数据(快照) • 定时或事件触发记录 • 包含:盘口、最新价、量、持仓 • 数据量:每天数千到数万条 • 特点:结构完整,状态清晰 • 用途:技术分析、策略回测 核心区别:逐笔成交告诉你「发生了什么」,Tick数据告诉你「当前状态是什么」

你看这张图就明白了。逐笔成交是流水账,Tick数据是快照。两者结合使用,才能还原市场的全貌。

我个人习惯的做法是:用Tick数据做策略回测,用逐笔成交做实时交易信号。为什么?因为Tick数据量小,回测快;逐笔成交细节多,适合捕捉瞬时机会。

2.4 实战中的注意事项

最后说几个实战中容易忽略的点:

  • 数据源的选择:不同数据商的逐笔成交数据,在时间精度和字段完整性上差异很大。我建议至少对比两家数据源,交叉验证。
  • 存储策略:逐笔成交数据量巨大。一只活跃股票一天可能产生几十万条。我习惯用列式存储(如Parquet),压缩比高,查询快。
  • 实时处理 vs 离线处理:实时处理用流式计算框架(如Flink),离线分析用批处理(如Spark)。不要混用。

一句话总结:逐笔成交是显微镜,Tick数据是望远镜。做订单流分析,两者缺一不可。

好了,这一章的内容就到这里。数据结构的底层逻辑搞清楚了,后面讲买卖压力计算的时候,你才能理解每个数字背后的含义。

专注资料整理