gs-quant商品期货价差交易:卡尔曼滤波更新方程设计

gs-quant商品期货价差交易:卡尔曼滤波更新方程设计

【免费下载链接】gs-quant 用于量化金融的Python工具包。 【免费下载链接】gs-quant 项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant

引言:商品期货价差交易的动态挑战

在商品期货市场中,价差交易(Spread Trading)是一种通过同时买入和卖出相关合约来获利的策略。这种策略的核心在于捕捉两个合约价格之间的均衡关系(Equilibrium Relationship) 偏离与回归的过程。传统方法如普通最小二乘法(OLS)静态线性回归,难以适应市场波动导致的关系时变特性。而卡尔曼滤波(Kalman Filter)作为一种递归状态估计算法,能够实时更新模型参数,为动态价差关系建模提供了理想解决方案。

本文将系统介绍如何基于gs-quant框架设计卡尔曼滤波更新方程,实现商品期货价差交易的动态对冲与套利。通过黄金(GC)与白银(SI)期货价差的实战案例,展示从状态空间模型构建到交易信号生成的完整流程。

卡尔曼滤波在价差交易中的数学原理

状态空间模型构建

商品期货价差通常表现为线性均衡关系:

y_t = α_t + β_t * x_t + ε_t

其中:

  • y_t:目标合约价格(如黄金期货)
  • x_t:对冲合约价格(如白银期货)
  • α_t:时变截距项(价差基线)
  • β_t:时变系数(对冲比率/Hedge Ratio)
  • ε_t:高斯白噪声残差(价差偏离)

卡尔曼滤波将该关系分解为状态方程观测方程

mermaid

核心更新方程设计

卡尔曼滤波通过两个关键步骤实现参数动态更新:

1. 预测步骤(Prediction)
# 状态预测
x_pred = F @ x_prev  # F为状态转移矩阵,此处设为单位矩阵
P_pred = F @ P_prev @ F.T + Q  # Q为过程噪声协方差矩阵
2. 更新步骤(Update)
# 卡尔曼增益计算
K = P_pred @ H.T @ np.linalg.inv(H @ P_pred @ H.T + R)  # R为观测噪声协方差

# 状态更新
x_new = x_pred + K @ (z - H @ x_pred)  # z为观测值

# 协方差更新
P_new = (np.eye(2) - K @ H) @ P_pred

其中状态向量 x = [α, β]^T,观测矩阵 H = [1, x_t]

gs-quant框架实现基础

核心工具函数适配

gs-quant的timeseries.statistics模块提供了必要的数学基础:

函数名用途代码示例
cov计算价格序列协方差cov(gs.Series(gc_prices), gs.Series(si_prices), window=60)
std滚动窗口标准差std(returns, window=Window(60))
zscores标准化残差信号zscores(spread_residuals, w=30)

数据获取与预处理

通过gs-quant获取连续期货合约数据:

from gs_quant.markets import Futures
from gs_quant.timeseries import returns

# 获取黄金/白银连续合约
gc = Futures('GC', 'NYMEX').get_historical_prices('1y', '1d')['close']
si = Futures('SI', 'NYMEX').get_historical_prices('1y', '1d')['close']

# 计算对数收益率
gc_ret = returns(gc, type='log')
si_ret = returns(si, type='log')

完整卡尔曼滤波更新方程实现

初始化参数设置

import numpy as np
import pandas as pd

# 状态初始值 [α, β]
x0 = np.array([0.0, 1.0])  # 初始对冲比率设为1

# 初始协方差矩阵
P0 = np.diag([1.0, 1.0])

# 过程噪声协方差(状态更新不确定性)
Q = np.diag([1e-5, 1e-5])

# 观测噪声协方差(价格波动不确定性)
R = 1e-4

递归更新算法实现

def kalman_filter_update(y, x, x0, P0, Q, R):
    """
    卡尔曼滤波更新方程实现
    
    参数:
        y: 目标合约价格序列
        x: 对冲合约价格序列
        x0: 初始状态向量
        P0: 初始协方差矩阵
        Q: 过程噪声矩阵
        R: 观测噪声方差
    
    返回:
        alpha: 时变截距项
        beta: 时变对冲比率
        residuals: 标准化价差残差
    """
    n = len(y)
    alpha = np.zeros(n)
    beta = np.zeros(n)
    residuals = np.zeros(n)
    
    # 初始化
    x_prev = x0
    P_prev = P0
    
    for t in range(n):
        # 状态预测
        x_pred = x_prev  # F=I
        P_pred = P_prev + Q  # F=I
        
        # 观测矩阵
        H = np.array([[1, x[t]]])
        
        # 卡尔曼增益
        K = P_pred @ H.T / (H @ P_pred @ H.T + R)
        
        # 状态更新
        z = y[t]
        x_new = x_pred + K.flatten() * (z - H @ x_pred)
        
        # 残差计算(价差偏离)
        residuals[t] = z - H @ x_new
        
        # 协方差更新
        P_new = (np.eye(2) - K @ H) @ P_pred
        
        # 存储结果
        alpha[t] = x_new[0]
        beta[t] = x_new[1]
        
        # 迭代
        x_prev = x_new
        P_prev = P_new
    
    # 残差标准化(使用gs-quant的zscores函数)
    from gs_quant.timeseries import zscores
    residuals = zscores(pd.Series(residuals), w=30)  # 30天滚动标准化
    
    return alpha, beta, residuals

实战案例:黄金-白银价差交易

数据准备与参数校准

# 获取GS-quant市场数据
from gs_quant.markets import get_history
from gs_quant.instrument import Future

# 定义黄金和白银期货合约
gc_future = Future('GCZ24', exchange='COMEX')  # 2024年12月黄金合约
si_future = Future('SIZ24', exchange='COMEX')  # 2024年12月白银合约

# 获取3个月价格数据
prices = get_history([gc_future, si_future], fields=['close'], start_date='2024-06-01', end_date='2024-09-01')
y = prices[gc_future.identifier]['close'].values  # 黄金价格序列
x = prices[si_future.identifier]['close'].values  # 白银价格序列

模型训练与结果可视化

# 运行卡尔曼滤波
alpha, beta, residuals = kalman_filter_update(y, x, x0, P0, Q, R)

# 结果可视化
import matplotlib.pyplot as plt

fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(12, 15))
ax1.plot(beta, label='时变对冲比率 β')
ax1.set_title('黄金-白银价差对冲比率动态变化')
ax1.legend()

ax2.plot(alpha, label='时变截距项 α')
ax2.set_title('价差基线动态变化')
ax2.legend()

ax3.plot(residuals, label='标准化价差残差')
ax3.axhline(2, color='r', linestyle='--', label='上阈值')
ax3.axhline(-2, color='g', linestyle='--', label='下阈值')
ax3.set_title('交易信号生成')
ax3.legend()

交易信号规则设计

基于标准化残差生成交易信号:

def generate_signals(residuals):
    """
    根据卡尔曼滤波残差生成交易信号
    
    信号规则:
    - 残差 > 2σ: 卖出差价(做空黄金,做多白银)
    - 残差 < -2σ: 买入价差(做多黄金,做空白银)
    - 残差在[-1σ, 1σ]区间: 平仓
    """
    signals = np.zeros(len(residuals))
    for t in range(1, len(residuals)):
        if residuals[t] > 2:
            signals[t] = -1  # 卖出差价
        elif residuals[t] < -2:
            signals[t] = 1   # 买入价差
        elif abs(residuals[t]) < 1:
            signals[t] = 0   # 平仓
        else:
            signals[t] = signals[t-1]  # 维持仓位
    return signals

signals = generate_signals(residuals)

基于gs-quant的策略回测框架

回测引擎集成

利用gs-quant的backtests模块实现策略评估:

from gs_quant.backtests import Backtest, Strategy, PositionSet
from gs_quant.instrument import Instrument

class SpreadTradingStrategy(Strategy):
    def __init__(self, signals, gc_identifier, si_identifier):
        self.signals = signals
        self.gc = gc_identifier
        self.si = si_identifier
        self.day = 0
    
    def enter_position(self, backtest: Backtest, dt: dt.datetime):
        signal = self.signals[self.day]
        positions = {}
        
        if signal == 1:  # 买入价差
            positions[self.gc] = 1  # 做多1手黄金
            positions[self.si] = -beta[self.day]  # 做空β手白银
        elif signal == -1:  # 卖出差价
            positions[self.gc] = -1  # 做空1手黄金
            positions[self.si] = beta[self.day]  # 做多β手白银
        else:
            positions = {}  # 平仓
        
        self.day += 1
        return PositionSet.from_dicts(positions)

# 初始化回测
strategy = SpreadTradingStrategy(signals, gc_future.identifier, si_future.identifier)
backtest = Backtest(strategy, start_date='2024-06-01', end_date='2024-09-01')
result = backtest.run()

# 性能评估
print(f"回测收益率: {result.total_return*100:.2f}%")
print(f"夏普比率: {result.sharpe_ratio:.2f}")
print(f"最大回撤: {result.max_drawdown*100:.2f}%")

卡尔曼滤波参数优化与鲁棒性分析

过程噪声协方差矩阵Q的校准

Q矩阵控制状态更新的平滑程度,通过网格搜索优化:

def optimize_Q(y, x):
    """网格搜索最优过程噪声协方差"""
    best_sharpe = -np.inf
    best_Q = None
    q_values = [1e-6, 5e-6, 1e-5, 5e-5, 1e-4]
    
    for q in q_values:
        Q = np.diag([q, q])
        _, _, residuals = kalman_filter_update(y, x, x0, P0, Q, R)
        signals = generate_signals(residuals)
        # 回测代码省略...
        sharpe = backtest_result.sharpe_ratio
        
        if sharpe > best_sharpe:
            best_sharpe = sharpe
            best_Q = Q
    
    return best_Q, best_sharpe

不同市场状态下的鲁棒性测试

通过gs-quant的scenario模块模拟极端行情:

from gs_quant.markets.scenario import HistoricalScenario

# 2020年3月疫情波动场景测试
scenario = HistoricalScenario(start_date='2020-03-01', end_date='2020-03-31')
with scenario:
    # 在历史波动场景下重新运行策略
    backtest_result = backtest.run()
    print(f"极端行情下回测收益率: {backtest_result.total_return*100:.2f}%")

结论与扩展应用

卡尔曼滤波通过动态更新价差关系的截距项与对冲比率,显著提升了商品期货价差交易的适应性。基于gs-quant框架实现的更新方程具有以下优势:

  1. 实时参数更新:相比静态OLS,能快速捕捉市场结构变化
  2. 噪声鲁棒性:通过协方差矩阵自适应调整,降低异常值影响
  3. 与量化框架无缝集成:可直接对接gs-quant的回测、风险管理模块

扩展应用方向

  1. 多因子状态扩展:将成交量、波动率等纳入状态向量
  2. 非线性扩展:使用扩展卡尔曼滤波处理非线性价差关系
  3. 高频交易优化:结合gs-quant的实时数据API实现低延迟交易

mermaid

【免费下载链接】gs-quant 用于量化金融的Python工具包。 【免费下载链接】gs-quant 项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值