3. 数据源获取与格式:常见Tick数据源、CSV/Parquet格式解析、数据加载与预览

Tick 数据的质量直接决定标签校准的成败,而数据源的选择与格式解析是第一步。本节将系统梳理主流 Tick 数据获取渠道、两种核心存储格式的差异,并给出标准的数据加载与预览流程。

3.1 常见Tick数据源对比

根据数据来源的权威性与覆盖范围,Tick 数据源可分为交易所直连、第三方数据商、开源社区三大类。下表从延迟、成本、数据完整性三个维度进行对比:

数据源类型 典型代表 延迟级别 成本 数据完整性 适用场景
交易所直连 CME Direct、SSE L1/L2 微秒级 极高(硬件+席位费) 完整(含撤销、错误交易) 高频做市、算法交易
第三方数据商 Refinitiv、Bloomberg、Wind 毫秒级 高(年订阅费) 高(清洗后,偶有缺失) 量化研究、回测
开源/社区 Polygon.io、Quandl、Dukascopy 秒级 低(免费或按量付费) 中等(可能存在时间戳截断) 教学、个人策略验证
实操建议: 标签校准对时间戳精度要求极高,优先选择带纳秒级时间戳的交易所直连或高端第三方数据。若使用开源数据,务必先做时间戳精度校验。

3.2 CSV与Parquet格式解析

Tick 数据在存储环节最常使用 CSV(文本格式)和 Parquet(列式二进制格式)。两种格式在读写性能、压缩比、Schema 支持上差异显著。

3.2.1 格式核心差异

对比维度 CSV Parquet
存储方式 行式文本 列式二进制
压缩率 低(通常 1:1~1:2) 高(Snappy/ZSTD 可达 1:5~1:10)
读取速度(全列) 慢(需逐行解析) 快(列裁剪 + 谓词下推)
Schema 支持 无(需外部定义) 内嵌(支持嵌套、可选字段)
时间戳精度 依赖字符串格式 原生支持纳秒级
典型文件大小(1天A股Tick) ~8 GB ~1.2 GB

3.2.2 格式选择原则

  • CSV:适合小规模数据(单日 < 500 MB)、快速预览、跨语言交换;缺点是解析慢、占用空间大。
  • Parquet:适合大规模生产环境(多日/多年 Tick)、需要频繁列查询、标签校准流水线;推荐作为主存储格式。
格式转换示例(Python): 将 CSV 批量转为 Parquet,同时统一时间戳列为纳秒级整数。
import pandas as pd
import pyarrow.parquet as pq
import pyarrow as pa

# 读取CSV
df = pd.read_csv('tick_20250101.csv', parse_dates=['timestamp'])
# 转换为纳秒级整数(避免时区歧义)
df['timestamp_ns'] = df['timestamp'].astype('int64')

# 写入Parquet,使用Snappy压缩
table = pa.Table.from_pandas(df)
pq.write_table(table, 'tick_20250101.parquet', compression='snappy')
print("转换完成,压缩比:", df.memory_usage(deep=True).sum() / 1e6, "MB →", 
      pq.read_metadata('tick_20250101.parquet').serialized_size / 1e6, "MB")

3.3 数据加载与预览

加载 Tick 数据时,必须关注三个关键点:时间戳对齐、缺失值处理、数据类型优化。以下给出标准加载流程。

3.3.1 加载流程步骤

  1. 指定 Schema:提前定义每列类型(时间戳→int64/nanosecond,价格→float64,成交量→int64)。
  2. 分区读取:按日期或合约分区,避免一次性加载全部数据。
  3. 时间戳校验:检查是否有重复时间戳、时间戳倒挂(后一笔早于前一笔)。
  4. 预览统计:输出行数、时间范围、缺失比例、基本统计量。

3.3.2 预览代码示例

import pandas as pd
import pyarrow.parquet as pq

# 加载Parquet文件,只读取前1000行用于预览
pf = pq.ParquetFile('tick_20250101.parquet')
first_batch = next(pf.iter_batches(batch_size=1000))
df_preview = first_batch.to_pandas()

# 基础信息
print("数据概览:")
print(f"  总行数(预估): {pf.metadata.num_rows}")
print(f"  时间范围: {df_preview['timestamp_ns'].min()} ~ {df_preview['timestamp_ns'].max()}")
print(f"  列名: {df_preview.columns.tolist()}")
print(f"  缺失值统计:\n{df_preview.isnull().sum()}")

# 检查时间戳顺序
time_diff = df_preview['timestamp_ns'].diff()
print(f"  时间戳倒挂数量: {(time_diff < 0).sum()}")
print(f"  重复时间戳数量: {df_preview['timestamp_ns'].duplicated().sum()}")

3.4 数据源与格式选择决策流程

以下 SVG 流程图展示了从数据源选择到格式落地的完整决策路径,帮助你在实际项目中快速定位最优方案。

Tick数据源与格式选择决策流程 Tick数据源与格式选择决策流程 获取Tick数据需求 选择数据源类型 交易所直连 第三方数据商 开源/社区 选择存储格式 CSV(小规模/预览) Parquet(生产/校准) 加载 → 预览 → 标签校准 说明:数据源决定时间戳精度与完整性;存储格式影响后续加载与校准效率。

3.5 常见问题与避坑

⚠️ 时间戳陷阱: 部分第三方数据商提供的 CSV 中,时间戳为字符串格式(如 "2025-01-01 09:30:00.123456"),但实际精度只到毫秒,后三位始终为 000。加载后务必检查最小时间间隔,避免将假精度用于标签校准。
  • 缺失值处理:Tick 数据中的 NaN 通常代表无交易或数据缺失,不要直接填充为 0,应标记为缺失并在校准阶段单独处理。
  • 分区策略:Parquet 推荐按 date + symbol 分区,避免单文件过大导致加载缓慢。
  • 内存管理:加载全量 Tick 数据时,使用 pd.read_csv(..., chunksize=50000) 或 pq.ParquetFile().iter_batches() 进行流式处理。