3. 时间基础概念
在多源金融数据对齐中,时间从来不是一个简单的字段,而是一组语义不同、来源不同、精度不同的坐标系统。同一笔成交,交易所记录的是撮合时刻,行情网关记录的是发出时刻,采集程序记录的是接收时刻,落库时又可能补上写入时刻。若不加区分地把它们都当作“时间”使用,后续对齐必然出现错位、重复或漏配。本节先把这些时间语义拆开,建立统一的时间坐标系。
一、四种时间语义:谁在什么时候说了什么
流式与批处理系统通常区分四类时间,它们在金融数据链路中各有明确位置:
- 事件时间(Event Time):业务事件真实发生的时刻,例如交易所撮合引擎生成成交回报的时间。它是语义上最准确的时间,也是事件时间对齐的首选基准。
- 摄入时间(Ingestion Time):数据进入采集或消息中间件的时刻,例如行情网关收到交易所报文的瞬间。它介于事件时间与处理时间之间,常用于无法获取可靠事件时间时的近似。
- 处理时间(Processing Time):计算引擎实际处理该条数据的机器时间,例如 Flink 算子调用
System.currentTimeMillis()的时刻。它最易获取,但受延迟、重放、背压影响最大,不适合作为金融对齐基准。 - 时间戳(Timestamp):附着在数据记录上的具体时间值,可能表示上述任意一种语义。关键不是“有没有时间戳”,而是“这个时间戳代表哪种语义”。
timestamp 直接当作事件时间。Kafka 消息时间戳默认可能是 CreateTime(生产者创建时间)或 LogAppendTime(Broker 写入时间),二者都不等于交易所撮合时间。二、时间戳的精度、时区与夏令时
金融数据的时间戳精度差异极大:交易所逐笔委托可能精确到微秒甚至纳秒,而日频基本面数据只有日期。对齐前必须统一到同一精度,并明确舍入规则——是截断、四舍五入还是向下取整到秒。精度不统一会造成“同一事件被分到不同时间桶”。
时区问题更隐蔽。交易所时间通常以本地时区发布:上交所、深交所使用 Asia/Shanghai,纽交所使用 America/New_York,伦交所使用 Europe/London。若采集端用 UTC 存储、分析端按本地时区解读,就会出现数小时偏移。正确做法是:存储统一用 UTC 或带偏移量的 ISO 8601 时间,展示和交易日判断时再转换到交易所本地时区。
夏令时(DST)是时区问题的放大器。美国、欧洲部分市场在夏季会将时钟拨快一小时,导致同一交易所的开盘时刻在 UTC 下发生偏移。例如纽交所常规交易时段在冬令时为 14:30–21:00 UTC,夏令时则变为 13:30–20:00 UTC。若系统硬编码 UTC 开盘时间,夏令时切换当天必然错位。
# 错误:硬编码 UTC 开盘时间
market_open_utc = "14:30"
# 正确:按交易所时区动态计算
from zoneinfo import ZoneInfo
from datetime import datetime, time
ny = ZoneInfo("America/New_York")
open_local = datetime.combine(date, time(9, 30), tzinfo=ny)
open_utc = open_local.astimezone(ZoneInfo("UTC"))
三、金融交易日历:不是所有“天”都是交易日
金融数据对齐不能只用自然日。交易日历定义了哪些日期开市、哪些休市、是否有半日交易、以及盘前盘后时段。不同市场的日历不同:A 股有春节、国庆长假,有感恩节、独立日,港股还受台风等临时休市影响。跨市场对齐时,必须使用各自市场的交易日历,再映射到统一时间轴。
| 概念 | 含义 | 对齐中的用途 |
|---|---|---|
| 事件时间 | 业务事件真实发生时刻 | 首选对齐基准 |
| 摄入时间 | 数据进入采集链路时刻 | 事件时间缺失时的近似 |
| 处理时间 | 计算引擎处理时刻 | 仅用于监控与延迟度量 |
| 时间戳 | 记录上的时间值 | 需先判定其语义 |
| 时区 | 时间表示的偏移规则 | 统一存储为 UTC |
| 夏令时 | 季节性时钟调整 | 动态计算开盘时刻 |
| 交易日历 | 开市/休市日期集合 | 过滤非交易日、定义交易时段 |
四、案例:跨市场开盘对齐的完整判断链
假设需要把 A 股与的逐笔成交按“开盘后第 N 分钟”对齐。处理流程如下:
- 读取每条成交的事件时间,确认其精度与时区;
- 将事件时间统一转换为 UTC 存储;
- 根据交易所交易日历判断该日是否开市,剔除休市日数据;
- 按交易所本地时区计算当日开盘时刻,注意夏令时;
- 计算
offset = event_time_utc - open_time_utc; - 按 offset 分桶,完成跨市场对齐。
五、误区复盘
- 误区一:所有时间戳都是事件时间。 实际可能是摄入或处理时间,需逐字段确认。
- 误区二:用自然日代替交易日。 周末与节假日会产生大量空桶或错配。
- 误区三:忽略夏令时。 切换日开盘偏移一小时,跨市场对齐整体错位。
- 误区四:时区混用不报错。 带时区与不带时区的时间直接相减,结果可能静默错误。
建立统一时间坐标系后,后续的多源对齐才有共同基准。核心原则可以概括为:以事件时间为准,以 UTC 存储,以交易所时区解释,以交易日历过滤,以统一精度分桶。任何一条数据进入对齐流程前,都应先回答“它的时间戳是什么语义、什么时区、什么精度”,否则对齐结果只是看似正确的数字。