5、基差交易的数据准备:数据源选择、数据清洗与对齐、基差计算与可视化、基差统计特征分析
做基差交易,说白了就是跟数据打交道。我见过太多人策略逻辑写得漂亮,结果数据源一塌糊涂,最后亏得莫名其妙。嗯,数据准备这事,看着基础,其实最考验功力。
5.1 数据源选择:别在源头就输了
我个人习惯把数据源分成三类:交易所直连、第三方数据商、免费公开数据。你想想看,不同场景下选择完全不同。
| 数据源类型 | 代表 | 延迟 | 成本 | 适用场景 |
|---|---|---|---|---|
| 交易所直连 | CTP、FIX | <1ms | 极高 | 高频套利、做市 |
| 第三方数据商 | Wind、聚宽、Tushare | 1-5s | 中等 | 日频策略、回测 |
| 免费公开数据 | Yahoo Finance、新浪 | 分钟级 | 免费 | 学习、初步研究 |
对于期货基差,我建议优先选Wind或聚宽。它们对期货的持仓量、结算价、主力合约切换都有专门处理。尤其是主力合约的连续性问题——很多新手在这上面栽过跟头。
5.2 数据清洗与对齐:脏数据比没数据更可怕
数据拿到手,第一件事不是算基差,而是清洗。我见过最离谱的情况:某天螺纹钢的收盘价突然跳了5%,查了半天发现是数据商把小数点搞错了。
我的清洗流程一般是这样的:
- 去重:同一时间戳出现多条记录,保留最后一条
- 缺失值处理:期货夜盘和日盘之间有空档,用前向填充
- 异常值检测:价格变动超过3个标准差,标记出来人工复核
- 时间对齐:现货和期货的交易时间不同,必须统一到同一时间轴
核心要点: 时间对齐是基差计算的前提。现货是连续交易,期货有开盘收盘。我习惯用期货的tick时间戳作为基准,把现货价格插值到对应时刻。
举个代码例子,这是我常用的对齐方式:
import pandas as pd
# 假设现货数据在 df_spot,期货数据在 df_future
# 以期货时间轴为基准
df_future['time'] = pd.to_datetime(df_future['time'])
df_spot['time'] = pd.to_datetime(df_spot['time'])
# 前向填充现货数据到期货时间点
df_spot.set_index('time', inplace=True)
df_spot_aligned = df_spot.reindex(df_future['time'], method='ffill')
# 合并
df = pd.concat([df_future, df_spot_aligned], axis=1)
df.columns = ['future_price', 'spot_price']
为什么会用前向填充而不是线性插值?因为现货价格在期货交易时段内,默认是最后成交价延续。线性插值反而会引入不存在的价格点。
5.3 基差计算与可视化:一眼看出机会
基差的计算公式很简单:基差 = 现货价格 - 期货价格。但实际应用中,有几点要注意:
- 正基差:现货贵,期货便宜。市场预期未来价格下跌
- 负基差:现货便宜,期货贵。市场预期未来价格上涨
- 基差率:基差 / 现货价格,用于跨品种比较
我个人习惯把基差和基差率都算出来。基差率能帮你判断当前偏离程度是否极端。
可视化方面,我推荐用折线图叠加柱状图:
import matplotlib.pyplot as plt
fig, ax1 = plt.subplots(figsize=(12, 6))
# 左轴:价格
ax1.plot(df.index, df['spot_price'], label='现货', color='blue')
ax1.plot(df.index, df['future_price'], label='期货', color='orange')
ax1.set_ylabel('价格')
# 右轴:基差
ax2 = ax1.twinx()
ax2.bar(df.index, df['basis'], label='基差', color='gray', alpha=0.3)
ax2.set_ylabel('基差')
plt.title('螺纹钢基差走势')
plt.show()
💡 小技巧: 把基差用柱状图放在价格下方,能直观看到基差的正负和大小。当柱状图突然变长或变短,往往意味着套利机会来了。
5.4 基差统计特征分析:用数据说话
光看图还不够,得用数字说话。我一般会算这几个统计量:
| 统计量 | 含义 | 交易意义 |
|---|---|---|
| 均值 | 基差的长期中枢 | 判断当前基差是否偏离正常水平 |
| 标准差 | 基差的波动幅度 | 设置入场/出场阈值 |
| 偏度 | 基差分布是否对称 | 正偏度意味着极端正基差更常见 |
| 峰度 | 基差分布的尾部厚度 | 高峰度意味着极端行情频发 |
| 自相关系数 | 基差的持续性 | 高自相关意味着趋势性强 |
举个例子,我做过螺纹钢的基差统计:
import numpy as np
basis = df['basis']
print(f"均值: {np.mean(basis):.2f}")
print(f"标准差: {np.std(basis):.2f}")
print(f"偏度: {np.skew(basis):.2f}")
print(f"峰度: {np.kurtosis(basis):.2f}")
print(f"自相关系数(1阶): {basis.autocorr():.2f}")
输出结果:
均值: 12.35
标准差: 45.67
偏度: 0.23
峰度: 3.45
自相关系数(1阶): 0.87
你看,均值12.35说明螺纹钢长期处于正基差状态。标准差45.67意味着基差波动很大,套利空间充足。自相关系数0.87——嗯,这很重要,说明基差有很强的趋势性,不是随机游走。
实战经验: 我曾经用这个统计框架做焦炭的基差分析。发现它的偏度是负的,意味着负基差(期货升水)更极端。后来我专门做空基差回归的策略,收益不错。说白了,统计特征能告诉你这个品种的「脾气」。
最后,我把整个数据准备的流程画了张图,方便你理解:
这张图把整个流程串起来了。从数据源到策略构建,每一步都环环相扣。记住,数据准备占整个基差交易工作量的60%以上。别急着跑策略,先把数据搞干净。
💡 最后提醒: 每次换品种或者换数据源,都要重新跑一遍统计特征。不同品种的基差「脾气」完全不同。螺纹钢和铁矿石,虽然都是黑色系,但统计特征天差地别。