2、Tick数据获取:从交易所获取Tick数据、从数据供应商获取Tick数据、本地Tick数据文件格式

做量化交易的朋友都知道,Tick数据是最高频的市场数据。每一笔成交、每一次报价变动,都被记录在Tick里。我刚开始接触Tick数据时,觉得这东西不就是一堆时间戳和价格嘛,有什么难的?后来真上手了才发现,坑多着呢。

今天咱们就聊聊Tick数据怎么来。说白了,就三条路:直接从交易所拿、从数据供应商买、或者用本地文件。每条路都有自己的脾气,咱们一条条说。

2.1 从交易所获取Tick数据

交易所是Tick数据的源头。国内常见的交易所包括上交所、深交所、中金所、大商所等。每个交易所都有自己的数据接口规范。

直接接入交易所的API,听起来很酷对吧?但实际操作起来,嗯,有点麻烦。

⚠️ 注意: 交易所API通常只对会员单位开放。个人投资者想直接接入?基本没戏。你得通过期货公司或券商来间接获取。

交易所提供的Tick数据接口,一般有两种方式:

  • 行情推送接口:实时推送,延迟低,适合做高频交易。我记得有次帮客户调试中金所的CTP接口,那延迟要求是微秒级的,稍微慢一点就被甩开了。
  • 历史数据下载:每天收盘后,交易所会提供当天的Tick数据文件。格式嘛,各家不一样。

举个例子,中金所的CTP(综合交易平台)接口,获取Tick数据的核心代码大概长这样:

# 伪代码示例 - CTP行情订阅
from ctp import MdApi

class TickHandler(MdApi):
    def OnRtnDepthMarketData(self, data):
        # 收到Tick数据回调
        tick = {
            'symbol': data.InstrumentID,
            'time': data.UpdateTime,
            'last_price': data.LastPrice,
            'volume': data.Volume,
            'bid_price': data.BidPrice1,
            'ask_price': data.AskPrice1
        }
        self.save_tick(tick)

api = TickHandler()
api.RegisterFront("tcp://180.168.146.187:10010")
api.Init()

你看,代码本身不复杂。但真正麻烦的是网络环境、防火墙、以及交易所的认证机制。我曾经在部署CTP接口时,被交易所的IP白名单折腾了整整两天——后来发现是公司网络出口IP变了。

2.2 从数据供应商获取Tick数据

如果你不是交易所会员,或者不想自己折腾底层接口,找数据供应商是最省心的办法。

国内常见的数据供应商有:

供应商 数据覆盖 接口方式 价格
Wind 股票、期货、期权 API / Excel插件 较贵
聚宽 股票、期货 Python SDK 中等
Tushare 股票、基金、期货 HTTP API 免费/付费
RiceQuant 股票、期货 Python SDK 中等

我个人习惯用Tushare做快速原型验证。免费版就能拿到日线数据,付费版才有Tick级别的数据。你想想看,如果只是做策略回测,日线数据够用了。但要做高频策略,Tick数据是必须的。

用Tushare获取Tick数据的示例:

import tushare as ts

# 设置token
ts.set_token('your_token_here')
pro = ts.pro_api()

# 获取某只股票的Tick数据
df = pro.tick(
    ts_code='000001.SZ',
    trade_date='20240115',
    start_time='093000',
    end_time='150000'
)
print(df.head())
💡 小技巧: 数据供应商的Tick数据通常已经做了初步清洗。但别太相信他们——我遇到过供应商数据里出现负价格的情况,明显是字段错位了。所以拿到数据后,一定要自己做一遍校验。

2.3 本地Tick数据文件格式

不管数据从哪来,最终都要存到本地。Tick数据量巨大,一天的数据可能就有几个GB。所以文件格式的选择很重要。

常见的本地存储格式有:

  • CSV:简单直观,但体积大、读写慢。适合小规模数据。
  • Parquet:列式存储,压缩率高,读写快。我强烈推荐这个。
  • HDF5:适合科学计算,但生态不如Parquet。
  • Feather:R和Python之间的桥梁,速度极快。

我自己在项目中,90%的情况都用Parquet。为什么?因为它的压缩比太香了。同样一份Tick数据,CSV要500MB,Parquet只要80MB。而且读取速度还快好几倍。

一个典型的Tick数据文件结构:

# Tick数据字段示例
{
    'symbol': 'IF2401',        # 合约代码
    'datetime': '2024-01-15 09:30:00.123',  # 精确到毫秒
    'last_price': 3850.2,      # 最新成交价
    'volume': 1234,            # 累计成交量
    'turnover': 47500000.0,    # 累计成交额
    'bid_price1': 3850.0,      # 买一价
    'bid_volume1': 10,         # 买一量
    'ask_price1': 3850.4,      # 卖一价
    'ask_volume1': 5,          # 卖一量
    'open_interest': 85000     # 持仓量(期货特有)
}
📌 重点: Tick数据的时间精度非常关键。交易所的时间戳通常是毫秒级,但有些供应商会截断到秒。如果你要做高频分析,时间精度不够的话,排序和去重都会出问题。

用Python读写Parquet格式的Tick数据:

import pandas as pd

# 读取Parquet文件
df = pd.read_parquet('tick_data.parquet')

# 写入Parquet文件
df.to_parquet('tick_data.parquet', compression='snappy')

# 查看数据概况
print(f"数据量: {len(df)} 条")
print(f"时间范围: {df['datetime'].min()} ~ {df['datetime'].max()}")

嗯,这里要注意一点:Parquet虽然好,但它不是万能的。如果你需要频繁地追加数据,Parquet就不太合适了。这时候可以考虑用Feather或者直接分文件存储。

2.4 知识体系总览

说了这么多,咱们用一张图来总结一下Tick数据获取的整体脉络:

Tick数据获取知识体系 交易所获取 数据供应商 本地文件存储 交易所API接入 • CTP / 飞马 / 金仕达 • 行情推送接口 • 历史数据下载 第三方数据服务 • Wind / 聚宽 / Tushare • REST API / SDK • 实时推送 / 历史查询 文件格式选择 • CSV / Parquet / HDF5 • 字段标准化 • 压缩与存储策略 Tick数据统一存储层 数据去重 → 排序 → 策略回测

这张图把Tick数据获取的三大路径串起来了。你从交易所拿原始数据,或者从供应商买现成的,最终都要落到本地存储。而本地存储的格式选择,直接决定了后续去重和排序的效率。

我个人建议:先用Tushare或聚宽快速拿到数据做验证,等策略跑通了,再考虑直接接入交易所API来降低延迟。别一上来就搞CTP,那玩意儿调试起来真能让人崩溃。

💡 避坑指南: 我曾经从某供应商买过一份期货Tick数据,拿到手发现时间戳全是乱的——有些是本地时间,有些是交易所时间,混在一起。后来我花了整整一周才把时间对齐。所以,拿到数据后第一件事:检查时间戳的时区和精度。

好了,Tick数据怎么来,咱们就聊到这儿。下一节咱们会深入讨论数据去重的具体算法——那才是真正考验功底的地方。


公众号:蓝海资料掘金营,微信deep3321