2、Tick数据获取:从交易所获取Tick数据、从数据供应商获取Tick数据、本地Tick数据文件格式
做量化交易的朋友都知道,Tick数据是最高频的市场数据。每一笔成交、每一次报价变动,都被记录在Tick里。我刚开始接触Tick数据时,觉得这东西不就是一堆时间戳和价格嘛,有什么难的?后来真上手了才发现,坑多着呢。
今天咱们就聊聊Tick数据怎么来。说白了,就三条路:直接从交易所拿、从数据供应商买、或者用本地文件。每条路都有自己的脾气,咱们一条条说。
2.1 从交易所获取Tick数据
交易所是Tick数据的源头。国内常见的交易所包括上交所、深交所、中金所、大商所等。每个交易所都有自己的数据接口规范。
直接接入交易所的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())
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 # 持仓量(期货特有)
}
用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数据获取的三大路径串起来了。你从交易所拿原始数据,或者从供应商买现成的,最终都要落到本地存储。而本地存储的格式选择,直接决定了后续去重和排序的效率。
我个人建议:先用Tushare或聚宽快速拿到数据做验证,等策略跑通了,再考虑直接接入交易所API来降低延迟。别一上来就搞CTP,那玩意儿调试起来真能让人崩溃。
好了,Tick数据怎么来,咱们就聊到这儿。下一节咱们会深入讨论数据去重的具体算法——那才是真正考验功底的地方。
公众号:蓝海资料掘金营,微信deep3321