第五节:基差数据采集与清洗——数据源选择、频率确定、异常值处理、对齐与插值
做基差交易,最怕什么?
不是行情看反,而是数据错了。
我见过太多交易员,策略逻辑没问题,模型跑得也漂亮,结果一上实盘就亏钱。查到最后,发现是基差数据里混进了几个异常值,或者两个市场的报价时间没对齐。说白了,数据是基差交易的命根子。这一节,我就把数据采集和清洗的实战经验掰开揉碎讲给你听。
5.1 数据源选择:三个渠道,各有脾气
基差数据涉及期货和现货两个市场。期货数据相对干净,现货数据才是真正的坑。我个人习惯把数据源分成三类:交易所、资讯商、现货市场。每个渠道的脾气都不一样。
5.1.1 交易所数据
交易所的数据最权威,也最规范。期货的收盘价、结算价、持仓量,这些直接从交易所接口拿就行。但要注意,交易所只提供期货数据,不提供现货数据。你拿不到现货报价,基差就算不出来。
常用交易所接口:
- 上期所、大商所、郑商所、中金所——官方数据源,延迟低,但需要申请权限
- CTP(综合交易平台)——很多量化交易者用这个,数据实时性好
- 易盛、飞马——部分期货公司提供,适合程序化交易
5.1.2 资讯商数据
资讯商是基差交易者的好帮手。他们不仅提供期货数据,还整合了现货报价。国内主流的资讯商有:
- Wind(万得)——金融圈标配,数据全,但贵。一个终端一年几万块,小团队可能扛不住
- Bloomberg(彭博)——国际品种必备,比如LME铜、CBOT大豆。价格更贵,但数据质量确实好
- Mysteel(我的钢铁)——黑色系品种的权威,螺纹钢、铁矿石的现货报价很准
- 卓创资讯——化工品、农产品覆盖不错,价格相对亲民
- 生意社——免费版也能用,但数据更新频率低,适合做周度分析
资讯商的数据有个问题:他们报的现货价,往往是市场均价或者参考价,不是真实成交价。你想想看,一个贸易商报的价,和实际成交价之间可能差个10块20块。这个误差在基差计算里,有时候会要命。
5.1.3 现货市场数据
如果你做的是产业客户套保,或者深度参与现货贸易,那最好自己采集现货数据。怎么采?
- 直接对接仓库/港口——比如做螺纹钢,可以跟上海钢联的仓库系统对接,拿到真实的出库价
- 贸易商报价群——很多品种有微信群、QQ群,贸易商每天会报买卖价。手动记录虽然累,但数据最真实
- 第三方平台——比如找钢网、欧冶云商,这些平台有真实的成交数据,但需要合作才能拿到
现货数据最大的问题是:非标准化。同样是螺纹钢,不同品牌、不同规格、不同地区,价格都不一样。你采集的时候,一定要把规格、品牌、地区、交货方式这些字段都记下来。不然数据一多,根本分不清哪个是哪个。
5.2 数据频率确定:日频、分钟频,还是Tick级?
数据频率怎么选?这取决于你的交易策略。
我一般这样分:
| 策略类型 | 推荐频率 | 原因 |
|---|---|---|
| 长周期套保(月/季度) | 日频 | 基差变化慢,日频足够捕捉趋势 |
| 中周期套利(周/月) | 日频或小时频 | 需要观察日内波动,但不必太精细 |
| 短周期高频交易 | 分钟频或Tick级 | 基差可能在几分钟内反转,必须高频 |
| 期现套利(日内) | 1分钟或5分钟 | 既要捕捉机会,又要控制数据量 |
这里有个坑:现货数据往往没有高频数据。大多数现货市场一天只报一次价,甚至一周报一次。你拿分钟频的期货数据去对日频的现货数据,基差曲线会很难看。怎么办?
- 如果现货数据是日频,那就把期货数据也降频到日频,用收盘价或结算价
- 如果现货数据是周频,那就用周均价,别想着做日内交易了
- 如果非要高频,那就自己建现货报价模型,用期货价格+升贴水来模拟
5.3 异常值处理:那些让你亏钱的“坏数据”
异常值,是基差数据里最隐蔽的杀手。我见过一个交易员,因为现货数据里混进了一个“0”,导致基差瞬间变成负数,他以为是套利机会,直接开仓,结果亏了20万。
异常值怎么处理?我总结了三步走:
5.3.1 识别异常值
常用的方法有:
- 3σ原则——计算均值和标准差,超过均值±3倍标准差的数据,标记为异常。适合正态分布的数据
- IQR(四分位距)——计算Q1和Q3,超出Q1-1.5*IQR或Q3+1.5*IQR的数据,标记为异常。适合非正态分布
- 业务规则——比如螺纹钢现货价不可能低于2000元/吨,也不可能高于8000元/吨。超出这个范围,直接剔除
我个人习惯用IQR,因为金融数据往往不是正态分布,3σ容易漏掉一些极端值。但IQR也有问题:如果数据本身波动大,可能会把正常值误判为异常。所以,我一般会结合业务规则一起用。
5.3.2 处理异常值
识别出来之后,怎么处理?
- 直接剔除——如果异常值数量少(比如不到1%),直接删掉。简单粗暴,但有效
- 替换为前值——用上一个正常值替换。适合价格缓慢变化的情况
- 替换为均值/中位数——用前后几期的均值替换。适合波动不大的数据
- 插值处理——用线性插值或样条插值。适合时间序列数据
5.3.3 代码示例:Python异常值处理
import pandas as pd
import numpy as np
# 假设df是包含基差数据的DataFrame,列名为'basis'
def detect_outliers_iqr(df, column='basis', multiplier=1.5):
Q1 = df[column].quantile(0.25)
Q3 = df[column].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - multiplier * IQR
upper_bound = Q3 + multiplier * IQR
outliers = (df[column] < lower_bound) | (df[column] > upper_bound)
return outliers
def handle_outliers(df, column='basis', method='ffill'):
outliers = detect_outliers_iqr(df, column)
if method == 'ffill':
df.loc[outliers, column] = df[column].shift(1).loc[outliers]
elif method == 'mean':
mean_val = df[column].mean()
df.loc[outliers, column] = mean_val
elif method == 'interpolate':
df.loc[outliers, column] = np.nan
df[column] = df[column].interpolate(method='linear')
return df
# 使用示例
df_clean = handle_outliers(df, column='basis', method='ffill')
5.4 数据对齐与插值:让期货和现货“对上话”
数据对齐,是基差计算中最烦人的一步。期货和现货的交易时间不一样,节假日也不一样。你拿一个上午10点的现货价,去对一个下午3点的期货价,算出来的基差能准吗?
5.4.1 时间对齐
对齐的核心是:找到同一时刻的期货和现货价格。但现实是,现货市场往往没有精确的时间戳。怎么办?
- 日频对齐——用期货的收盘价对现货的日度均价。这是最常用的方法,简单可靠
- 分钟频对齐——如果现货有高频数据,那就用期货的对应分钟K线。比如现货10:00报价,就用期货10:00的成交价
- 事件对齐——比如某个品种的现货报价只在上午10点和下午2点发布,那就只在这两个时间点取期货数据
这里有个细节:期货的夜盘。很多品种有夜盘,但现货市场晚上不开门。如果你用夜盘的期货价去对白天的现货价,基差会失真。我一般会把夜盘数据单独处理,或者只取日盘的数据。
5.4.2 节假日对齐
期货市场有夜盘,现货市场没有。期货市场节假日也交易(比如春节前最后一天),但现货市场早就放假了。这会导致数据缺失。
我的处理方法是:
- 剔除节假日——只保留期货和现货都有交易的日子。这样数据最干净,但样本量会减少
- 填充前值——如果现货缺失,就用前一个交易日的现货价填充。适合现货价格变化不大的情况
- 插值——用线性插值填充缺失的现货数据。适合价格趋势明显的情况
5.4.3 插值方法选择
插值,说白了就是“猜”缺失的数据。常用的方法有:
| 插值方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 线性插值 | 价格变化平稳 | 简单、计算快 | 无法捕捉突变 |
| 样条插值 | 价格有趋势 | 曲线平滑 | 容易过拟合 |
| 前值填充 | 价格变化小 | 最保守 | 忽略趋势 |
| 后值填充 | 价格变化小 | 适合回测 | 有未来信息 |
我个人最常用的是线性插值。简单,而且不容易出错。但如果你做的是高频交易,样条插值可能更合适,因为它能更好地拟合价格曲线。
5.5 知识体系总览
下面这张图,把基差数据采集与清洗的核心逻辑串起来了。你可以把它当成一个检查清单,每次做数据前,先过一遍。
好了,数据采集与清洗这部分就讲到这里。记住一句话:数据质量决定策略上限。你花再多时间在数据上,都不为过。下一节,我们会聊基差的计算方法与价差分析,到时候见。
公众号:蓝海资料掘金营,微信deep3321