2. Tick数据获取:常见Tick数据源介绍与Python获取方法

Tick数据是量化回测的“原油”,其质量与获取方式直接影响策略的精度与可靠性。本章将系统梳理主流Tick数据源,并演示通过Python API与CSV文件两种方式获取Tick数据的具体方法。

2.1 常见Tick数据源对比

根据数据来源与合规性,Tick数据源可分为交易所直连、数据商代理、社区共享三类。下表从数据精度、成本、获取难度三个维度进行对比:

数据源类型 典型代表 数据精度 成本 获取难度 适用场景
交易所直连 上交所L1/L2、深交所L1/L2、CME 最高(逐笔委托/成交) 极高(会员费+行情费) 高(需机构资质) 机构高频、做市商
专业数据商 Wind、聚宽、RiceQuant、Tushare 高(快照Tick) 中高(年费/积分) 中(API申请) 中低频回测、因子研究
社区/开源 AKShare、Yahoo Finance(延迟) 低(分钟级或延迟Tick) 免费 低(pip安装) 学习、原型验证
选型建议: 个人量化研究者优先选择专业数据商(如Tushare Pro或AKShare),兼顾数据质量与成本;机构用户应直接对接交易所或购买L2行情。

2.2 交易所Tick数据体系

交易所是Tick数据的最终源头。以国内A股为例,Level-1与Level-2行情在数据维度上存在显著差异:

  • Level-1(基础行情):每3秒快照一次,包含最新价、成交量、五档买卖盘口。适合日频或分钟级回测。
  • Level-2(极速行情):逐笔成交与逐笔委托,时间戳精确到毫秒甚至微秒。支持订单流分析与高频策略。

下图展示了从交易所原始逐笔数据到用户可用的Tick数据帧的流转链路:

交易所Tick数据流转链路 交易所撮合引擎 逐笔成交/委托 行情网关 组播/推送 数据商服务器 清洗/存储/API CSV文件 本地存储/离线回测 Python API 实时/历史获取 数据库 InfluxDB/ClickHouse 说明:用户通常通过数据商API或CSV文件间接获取Tick数据,极少直接对接交易所撮合引擎

2.3 Python获取Tick数据:API方式

通过数据商提供的Python SDK,可以高效获取历史Tick数据。以下以Tushare Pro为例,展示获取某只股票某日Tick数据的标准流程:

import tushare as ts

# 设置token(需在tushare官网注册获取)
pro = ts.pro_api('your_token_here')

# 获取2024年1月2日贵州茅台(600519.SH)的Tick数据
df = pro.tick_data(
    ts_code='600519.SH',
    trade_date='20240102',
    start_time='093000',
    end_time='150000'
)

# 查看前5行
print(df.head())

# 输出示例:
#        ts_code  trade_date  trade_time   price  vol  amount  buy  sell
# 0  600519.SH    20240102     093000  1685.0   10   16850    1     2
# 1  600519.SH    20240102     093001  1685.2    5    8426    1     1
# 2  600519.SH    20240102     093002  1685.1   20   33702    2     3
API调用要点:
  • 大部分数据商对Tick数据有调用频率限制(如每分钟最多200次),需合理控制请求间隔。
  • 历史Tick数据通常只保留近1-3年,更早的数据需通过数据商VIP接口或购买离线数据集。
  • 返回的DataFrame中,trade_time字段通常为字符串格式,需转换为datetime以便后续时间序列处理。

2.4 Python获取Tick数据:CSV读取方式

对于已下载到本地的Tick CSV文件,使用Pandas读取并做初步清洗是回测前的标准步骤。典型的Tick CSV文件包含以下字段:

字段名 类型 说明
datetime str 日期时间,格式如 2024-01-02 09:30:00.123
price float 成交价格
volume int 成交量(股)
amount float 成交金额(元)
direction str 买卖方向:B(买)/S(卖)/N(中性)
import pandas as pd

# 读取Tick CSV文件
df = pd.read_csv(
    'tick_data_600519_20240102.csv',
    parse_dates=['datetime'],
    dtype={
        'price': 'float64',
        'volume': 'int32',
        'amount': 'float64',
        'direction': 'category'
    }
)

# 按时间排序(确保时间顺序)
df.sort_values('datetime', inplace=True)

# 重置索引
df.reset_index(drop=True, inplace=True)

# 检查缺失值
print(f"缺失值统计:\n{df.isnull().sum()}")

# 查看数据范围
print(f"时间范围: {df['datetime'].min()} ~ {df['datetime'].max()}")
print(f"总Tick数: {len(df)}")
CSV读取常见陷阱:
  • 时间戳精度丢失:CSV中毫秒/微秒可能被截断,读取时需指定parse_dates的格式,如format='%Y-%m-%d %H:%M:%S.%f'。
  • 大文件内存溢出:单日Tick数据约10-50万行,多日合并可能达数千万行。建议使用chunksize分块读取或转为Parquet格式。
  • 字段类型错误:volume可能被读为float,需显式指定dtype为int。

2.5 数据质量校验与预处理

无论通过API还是CSV获取,Tick数据都需要经过以下质量检查才能用于回测:

  1. 时间连续性检查:检查是否存在时间跳跃或重复时间戳。
  2. 价格合理性检查:价格是否在当日涨跌停范围内,是否存在负价格或异常跳变。
  3. 成交量检查:单笔成交量是否超过市场合理阈值(如A股单笔最大100万手)。
  4. 买卖方向一致性:检查direction字段是否与价格变动逻辑一致。
# 简单质量检查示例
# 1. 检查重复时间戳
duplicates = df[df.duplicated(subset=['datetime'], keep=False)]
if len(duplicates) > 0:
    print(f"发现 {len(duplicates)} 条重复时间戳")

# 2. 检查价格是否在合理范围(假设前收盘价1680,涨跌停±10%)
prev_close = 1680.0
lower_limit = prev_close * 0.9
upper_limit = prev_close * 1.1
out_of_range = df[(df['price'] < lower_limit) | (df['price'] > upper_limit)]
if len(out_of_range) > 0:
    print(f"发现 {len(out_of_range)} 条价格异常数据")

# 3. 检查单笔成交量是否异常
max_volume = 1000000  # 100万手
abnormal_vol = df[df['volume'] > max_volume]
if len(abnormal_vol) > 0:
    print(f"发现 {len(abnormal_vol)} 条成交量异常数据")
数据清洗原则: 对于异常数据,优先标记而非直接删除。在回测中可设置“数据质量过滤器”,将异常Tick标记为无效,避免影响策略信号计算。

通过以上方法,你可以从不同数据源获取Tick数据,并完成基本的清洗与校验,为后续的收益回测打下坚实的数据基础。