4. 价差可视化分析:K线图、价差曲线、相关性热力图

好,咱们进入第四讲。前面几章我们把价差的计算逻辑、数据清洗讲透了,现在该让数据「开口说话」了。

我个人习惯,拿到一组价差数据,第一件事不是跑模型,而是画图。为什么?因为图形能告诉你很多统计指标掩盖掉的细节——比如某个时间段的异常波动、结构性的偏移、或者某些品种之间「说不清道不明」的联动关系。

这一章,咱们就聚焦三种最常用的可视化手段:价差K线图价差曲线相关性热力图。这三种图,基本覆盖了从微观到宏观、从单品种到多品种的分析需求。

4.1 价差K线图:把价差当「品种」来交易

很多新手做套利,只看价差的收盘价序列。这其实不够。你想想看,价差在一天之内可能剧烈波动,只看收盘价会错过很多日内交易机会。

我的做法是:把价差当成一个独立的交易品种,给它画K线图。这样你就能看到价差的开盘、最高、最低、收盘,也就是OHLC数据。

我的经验: 价差K线图特别适合识别「假突破」。比如价差收盘价看起来突破了某个阈值,但日内最高价其实早就突破又回来了——这种信号,收盘价序列根本看不出来。

下面这段代码,演示如何从两个期货合约的分钟数据生成价差K线:

import pandas as pd
import mplfinance as mpf

# 假设 df_contract1 和 df_contract2 是分钟级OHLC数据
# 先计算每分钟的价差
df_spread = pd.DataFrame()
df_spread['open'] = df_contract1['open'] - df_contract2['open']
df_spread['high'] = df_contract1['high'] - df_contract2['high']
df_spread['low'] = df_contract1['low'] - df_contract2['low']
df_spread['close'] = df_contract1['close'] - df_contract2['close']
df_spread.index = df_contract1.index  # 保持时间索引

# 用 mplfinance 画K线图
mpf.plot(df_spread, type='candle', volume=False,
         title='价差K线图 - 螺纹钢与热卷',
         style='charles', figsize=(12,6))

嗯,这里要注意:价差K线的最高价不一定等于两个合约最高价之差。因为两个合约的最高价可能不在同一时刻出现。所以计算时要逐笔对齐时间戳,不能偷懒。

4.2 价差曲线:趋势与回归的直观呈现

价差曲线是最基础、也最直观的图。说白了就是把价差的时间序列画成一条线。但别小看它,很多交易决策就靠这条线。

我个人习惯在价差曲线上叠加三条辅助线:

  • 均值线:通常是滚动均值,比如20期或60期
  • 上下轨:均值 ± k倍标准差,k一般取1.5或2
  • 零轴:如果价差是经过协整回归的残差,零轴就是均衡线

我曾经犯过一个错误:用全样本均值做基准线。结果回测很漂亮,实盘一跑就亏。后来才发现,全样本均值包含了未来的数据,属于「未来函数」。正确的做法是用滚动窗口。

import matplotlib.pyplot as plt
import numpy as np

# 假设 spread 是价差序列
window = 60
spread_mean = spread.rolling(window=window).mean()
spread_std = spread.rolling(window=window).std()
upper_band = spread_mean + 2 * spread_std
lower_band = spread_mean - 2 * spread_std

plt.figure(figsize=(14,6))
plt.plot(spread.index, spread, label='价差', color='blue', alpha=0.7)
plt.plot(spread.index, spread_mean, label=f'{window}期均值', color='orange', linestyle='--')
plt.fill_between(spread.index, upper_band, lower_band, alpha=0.2, color='gray', label='±2σ 通道')
plt.axhline(0, color='red', linestyle=':', alpha=0.5)
plt.legend()
plt.title('价差曲线与布林通道')
plt.show()
实战要点: 当价差触及上下轨时,不要立刻入场。我一般会等价格「刺破」轨道后再回到轨道内,才确认信号。这样可以过滤掉很多假突破。

4.3 相关性热力图:发现隐藏的联动关系

做跨市场套利,你不可能只盯着一对品种。很多时候,A和B的价差波动,其实是受到C的影响。这时候就需要相关性热力图来帮你「看清全局」。

我通常的做法是:计算多个品种之间的滚动相关性,而不是静态的全局相关性。因为市场环境在变,相关性也在变。

import seaborn as sns

# 假设 df_prices 是多品种的收盘价DataFrame
# 计算收益率
returns = df_prices.pct_change().dropna()

# 计算滚动相关性矩阵(这里用60期窗口)
rolling_corr = returns.rolling(window=60).corr()

# 取最新一期的相关性矩阵
latest_corr = rolling_corr.iloc[-len(df_prices.columns):].unstack().iloc[:len(df_prices.columns)]

# 或者更直接:取最后一个时间点的矩阵
latest_corr_matrix = returns.rolling(window=60).corr().groupby(level=0).last().iloc[-1].unstack()

# 画热力图
plt.figure(figsize=(10,8))
sns.heatmap(latest_corr_matrix, annot=True, cmap='coolwarm', center=0,
            square=True, linewidths=0.5)
plt.title('品种间收益率滚动相关性热力图(60期)')
plt.show()
避坑指南: 我曾经用日线数据算相关性,结果发现两个品种相关性高达0.95,兴冲冲地做了配对交易。后来才发现,它们都是跟踪同一个指数的ETF,本质上就是同一个东西。所以,算相关性之前,先确认品种之间是否有「逻辑上的独立性」。

4.4 三种图的组合应用策略

这三种图不是孤立的。我一般这样组合使用:

分析层次 使用图形 解决什么问题
微观入场点 价差K线图 识别日内假突破、确认入场时机
中观趋势判断 价差曲线 + 布林通道 判断价差是否处于极端位置、是否均值回归
宏观品种筛选 相关性热力图 发现潜在套利对、排除伪相关品种

举个例子:我通过热力图发现螺纹钢和热卷的相关性在0.85以上,于是把它们作为套利对。然后看价差曲线,发现当前价差处于下轨附近。再切到分钟级K线图,确认没有出现「假突破」的形态。三图印证,我才敢下单。

4.5 本章知识体系

下面这张图,帮你把本章的核心逻辑串起来:

价差可视化分析体系 价差K线图 价差曲线 相关性热力图 微观入场点 识别日内假突破 确认入场时机 中观趋势判断 判断极端位置 均值回归信号 宏观品种筛选 发现套利对 排除伪相关 三图印证 → 交易决策

说白了,这三种图就是你的「三重视角」:K线图看细节,价差曲线看趋势,热力图看全局。三者结合,才能做出靠谱的交易判断。

我的建议: 刚开始做套利的朋友,先别急着上复杂模型。把这三张图画熟练,你就能过滤掉至少一半的无效交易信号。剩下的,才是真正值得下注的机会。

好了,这一章就到这里。记住:图形不是装饰,是决策工具。下一章我们会把这些可视化方法应用到实盘监控中,到时候你会看到它们真正的威力。


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