3、Tick数据结构解析:时间戳、价格、成交量、买卖盘口等字段详解

做量化交易的朋友都知道,Tick数据是市场的“原子”记录。每一笔成交、每一次报价变动,都被忠实地记录下来。但说实话,我刚入行那会儿,面对一堆密密麻麻的字段,也是一头雾水。

今天我就带你把这层窗户纸捅破。咱们把Tick数据里最核心的几个字段——时间戳、价格、成交量、买卖盘口——一个一个拆开来看。搞懂了这些,后面的清洗和特征工程才能玩得转。

3.1 时间戳:市场的“心跳”

时间戳是Tick数据的灵魂。没有它,所有数据都是死的。

我见过不少新手,拿到数据第一件事就是看价格,结果分析半天发现时间对不上。嗯,这里要特别注意:时间戳的精度和时区,是第一个坑

核心要点:

  • 精度:国内A股通常是毫秒级(3位小数),期货可能是微秒级(6位小数)。高频策略对精度要求极高,差1毫秒可能就是天壤之别。
  • 时区:国内数据一般是北京时间(UTC+8)。但有些数据商可能给你的是UTC时间,不转换直接分析,结果全乱套。
  • 格式:常见的有Unix时间戳(整数或浮点数)和字符串格式(如"2024-01-15 09:30:00.123")。

我的习惯:拿到数据后,第一件事就是把时间戳统一转换成datetime64[ns]类型,并强制设定时区。这样后续所有操作都基于同一个时间基准,不会出幺蛾子。

举个例子,看看Python里怎么处理:

import pandas as pd

# 假设原始时间戳是Unix毫秒
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')

# 强制设定为北京时间
df['timestamp'] = df['timestamp'].dt.tz_localize('UTC').dt.tz_convert('Asia/Shanghai')

# 去掉时区信息,方便计算
df['timestamp'] = df['timestamp'].dt.tz_localize(None)

为什么会这样?因为很多计算库(比如numpy)对带时区的datetime支持不好,容易报错。去掉时区后,我们心里清楚它代表的是北京时间就行。

3.2 价格:成交的“锚点”

价格字段看起来简单,但里面门道不少。我遇到过最离谱的一次,是某个数据源把“昨收价”和“最新价”搞混了,导致我回测的夏普比率直接翻倍……还好发现得早。

常见的价格字段有这几个:

字段名 含义 注意事项
LastPrice 最新成交价 这是最常用的价格,但要注意它可能不是连续的
BidPrice1 买一价 最高买入申报价
AskPrice1 卖一价 最低卖出申报价
OpenPrice 开盘价 集合竞价后的第一笔成交价
HighPrice / LowPrice 当日最高/最低价 注意是当日累计,不是当前Tick的

避坑指南:我曾经在清洗期货数据时,发现某天的最高价比涨停板还高。查了半天,原来是数据商把下一交易日的预埋单价格也录进来了。所以,价格字段一定要做上下限校验,比如对照涨跌停板、昨收价等。

价格清洗的一个常用技巧是“价格跳变检测”。如果相邻两个Tick的价格差超过了某个阈值(比如1%),那很可能是数据错误,需要标记出来人工复核。

# 价格跳变检测
threshold = 0.01  # 1%的阈值
price_diff = df['LastPrice'].pct_change()
suspicious = price_diff.abs() > threshold

print(f"发现 {suspicious.sum()} 个可疑价格跳变点")

3.3 成交量:市场的“呼吸”

成交量反映了市场的活跃程度。但Tick级别的成交量,和日线级别的成交量,理解起来不太一样。

在Tick数据里,成交量通常有两种:

  • Volume:当前Tick的成交量(即这一笔成交了多少手/股)
  • TotalVolume:从开盘到现在的累计成交量

我个人习惯用Volume,因为它能直接反映每一笔交易的“力度”。比如,同样是价格上涨1个tick,如果成交量是100手和1000手,背后的含义完全不同。

一个实用的特征:计算“每笔成交量”的均值。如果某笔成交量突然放大到均值的5倍以上,往往意味着有大资金在行动。这个特征在捕捉“主力异动”时非常有用。

成交量清洗时要注意:

  • 成交量不能为负数(废话,但真的有人遇到过)
  • 累计成交量应该是单调递增的,如果出现下降,说明数据有重复或乱序
  • 对于期货,要注意合约换月时成交量的“断崖”变化

3.4 买卖盘口:市场的“情绪”

买卖盘口,也就是我们常说的“十档行情”或“五档行情”。它展示了当前市场上所有未成交的买单和卖单。

常见的字段包括:

  • BidPrice1~BidPrice5:买一到买五的价格
  • BidVolume1~BidVolume5:买一到买五的挂单量
  • AskPrice1~AskPrice5:卖一到卖五的价格
  • AskVolume1~AskVolume5:卖一到卖五的挂单量

盘口数据里藏着很多信息。比如:

  • 买卖价差(Spread) = AskPrice1 - BidPrice1。价差越小,流动性越好。
  • 订单簿不平衡(Order Imbalance) = (BidVolume1 - AskVolume1) / (BidVolume1 + AskVolume1)。正值表示买方力量强,负值表示卖方力量强。
  • 深度(Depth):某个价格区间内的总挂单量。深度越厚,价格越不容易被操纵。

我常用的一个技巧:计算“盘口压力比”。比如,把买一到买五的总量除以卖一到卖五的总量。如果这个比值突然从1.2掉到0.8,说明卖方压力骤增,可能是下跌的前兆。当然,这只是一个信号,不能单独作为交易依据。

盘口数据清洗的难点在于:

  • 价格和数量必须匹配(比如BidPrice1不能比BidPrice2还低)
  • 价格必须在合理范围内(不能出现负价格或离谱的高价)
  • 挂单量不能为负数(虽然很少见,但数据损坏时可能发生)

3.5 知识体系总览

说了这么多,咱们用一张图来总结一下Tick数据的核心字段和它们之间的关系:

Tick数据结构核心字段 Tick数据 时间戳 价格 成交量 买卖盘口(五档/十档) 精度(毫秒/微秒) 时区处理 最新价/买卖价 涨跌停校验 单笔/累计 单调递增检查 买卖价差 订单簿不平衡 深度分析 清洗要点:精度校验 | 范围校验 | 逻辑校验 | 单调性校验

这张图把咱们刚才讲的内容串起来了。你看,Tick数据虽然字段多,但核心就这四大块。每一块都有它的清洗要点和特征提取方法。

说实话,搞懂这些字段只是第一步。真正有价值的是,你能从这些原始字段里“挖”出什么特征来。比如,把时间戳和价格结合起来,可以计算“每笔价格变化的速度”;把成交量和盘口结合起来,可以判断“大单是主动买入还是卖出”。

嗯,这些内容咱们后面的章节会详细展开。今天先把地基打牢,后面的高楼才能盖得稳。

总结一下今天的核心收获:

  1. 时间戳要注意精度和时区,统一转换成标准格式
  2. 价格要做上下限校验,防止异常值污染数据
  3. 成交量要区分单笔和累计,检查单调性
  4. 盘口数据可以衍生出价差、不平衡度、深度等特征

下次你拿到一份Tick数据,别急着跑策略。先花10分钟,把上面这些字段检查一遍。相信我,这10分钟能帮你省下后面10小时的debug时间。


专注资料整理