【期货量化实战】跨期套利策略:价差交易完整指南(TqSdk源码详解)

一、前言

跨期套利是期货市场中最经典的套利策略之一,通过同时买卖同一品种不同月份的合约,利用价差回归获利。相比单边趋势交易,套利策略风险更低、收益更稳定。

本文将介绍:

  • 跨期套利的基本原理
  • 价差计算与监控
  • 套利信号判断
  • TqSdk完整实现代码

二、为什么选择天勤量化(TqSdk)

在众多期货量化工具中,**天勤量化(TqSdk)**是目前国内最受欢迎的开源期货量化框架之一:

特点 说明
完全免费 开源免费,无需付费即可获取实时行情
数据全面 支持国内所有期货交易所的实时行情和历史数据
上手简单 几行Python代码即可获取数据
文档完善 官方文档详细,示例代码丰富

安装方法

bash 复制代码
pip install tqsdk

三、跨期套利基础

3.1 什么是跨期套利

跨期套利(Calendar Spread)是指在同一期货品种的不同交割月份合约上建立数量相等、方向相反的头寸。

类型 操作 预期
正套 买近月卖远月 价差扩大
反套 卖近月买远月 价差缩小

3.2 价差类型

价差形态 说明 常见品种
正价差(Contango) 远月价格 > 近月价格 仓储成本品种
负价差(Backwardation) 近月价格 > 远月价格 供需紧张品种

3.3 套利优势

优势 说明
风险较低 对冲了大部分方向性风险
保证金优惠 交易所通常有套利保证金优惠
收益稳定 价差波动相对可预测
适合大资金 容量大、冲击成本低

四、完整代码实现

4.1 价差监控工具

python 复制代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:跨期价差实时监控
说明:本代码仅供学习参考
"""

from tqsdk import TqApi, TqAuth

# ============ 合约配置 ============
SYMBOL_NEAR = "SHFE.rb2505"   # 近月合约
SYMBOL_FAR = "SHFE.rb2510"    # 远月合约

# ============ 初始化 ============
api = TqApi(auth=TqAuth("快期账户", "快期密码"))

quote_near = api.get_quote(SYMBOL_NEAR)
quote_far = api.get_quote(SYMBOL_FAR)

print("=" * 60)
print("跨期价差监控")
print("=" * 60)
print(f"近月合约: {SYMBOL_NEAR}")
print(f"远月合约: {SYMBOL_FAR}")
print("-" * 60)

# 价差历史
spread_history = []

while True:
    api.wait_update()
    
    # 获取最新价格
    price_near = quote_near.last_price
    price_far = quote_far.last_price
    
    # 计算价差(远月 - 近月)
    spread = price_far - price_near
    spread_history.append(spread)
    
    # 保留最近100个数据计算统计值
    if len(spread_history) > 100:
        spread_history = spread_history[-100:]
    
    # 计算统计指标
    avg_spread = sum(spread_history) / len(spread_history)
    max_spread = max(spread_history)
    min_spread = min(spread_history)
    
    print(f"\r近月={price_near:.0f} 远月={price_far:.0f} "
          f"价差={spread:.0f} 均值={avg_spread:.0f} "
          f"区间=[{min_spread:.0f}, {max_spread:.0f}]", end="")

4.2 完整套利策略

python 复制代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:跨期套利策略
说明:本代码仅供学习参考
"""

from tqsdk import TqApi, TqAuth, TqSim
from tqsdk.lib import TargetPosTask
import numpy as np

# ============ 合约配置 ============
SYMBOL_NEAR = "SHFE.rb2505"   # 近月合约
SYMBOL_FAR = "SHFE.rb2510"    # 远月合约
LOTS = 1                      # 每腿手数

# ============ 策略参数 ============
LOOKBACK = 60                 # 回看周期
ENTRY_THRESHOLD = 2.0        # 开仓阈值(标准差倍数)
EXIT_THRESHOLD = 0.5         # 平仓阈值
MAX_HOLD_BARS = 100          # 最大持仓K线数

# ============ 初始化 ============
api = TqApi(TqSim(init_balance=500000), auth=TqAuth("快期账户", "快期密码"))

quote_near = api.get_quote(SYMBOL_NEAR)
quote_far = api.get_quote(SYMBOL_FAR)
kline_near = api.get_kline_serial(SYMBOL_NEAR, 300, LOOKBACK + 20)
kline_far = api.get_kline_serial(SYMBOL_FAR, 300, LOOKBACK + 20)

# 持仓管理
target_pos_near = TargetPosTask(api, SYMBOL_NEAR)
target_pos_far = TargetPosTask(api, SYMBOL_FAR)

account = api.get_account()

print("=" * 60)
print("跨期套利策略")
print("=" * 60)
print(f"近月: {SYMBOL_NEAR}")
print(f"远月: {SYMBOL_FAR}")
print(f"开仓阈值: {ENTRY_THRESHOLD}倍标准差")
print(f"平仓阈值: {EXIT_THRESHOLD}倍标准差")
print("-" * 60)

# 状态变量
position = 0       # 1=正套(买近卖远), -1=反套(卖近买远), 0=空仓
hold_bars = 0      # 持仓K线数

while True:
    api.wait_update()
    
    if api.is_changing(kline_near.iloc[-1], "datetime"):
        # 获取收盘价序列
        close_near = kline_near["close"].values[-LOOKBACK:]
        close_far = kline_far["close"].values[-LOOKBACK:]
        
        # 计算价差序列
        spread = close_far - close_near
        
        # 统计指标
        spread_mean = np.mean(spread)
        spread_std = np.std(spread)
        
        # 当前价差
        current_spread = close_far[-1] - close_near[-1]
        
        # 计算z-score
        z_score = (current_spread - spread_mean) / spread_std if spread_std > 0 else 0
        
        print(f"\n价差={current_spread:.0f} 均值={spread_mean:.0f} "
              f"标准差={spread_std:.0f} Z值={z_score:.2f}")
        
        # ============ 交易逻辑 ============
        if position == 0:
            # 无持仓,判断开仓
            if z_score > ENTRY_THRESHOLD:
                # 价差过大,做反套(卖近买远)
                target_pos_near.set_target_volume(-LOTS)
                target_pos_far.set_target_volume(LOTS)
                position = -1
                hold_bars = 0
                print(f"[开仓] 反套:卖{SYMBOL_NEAR} 买{SYMBOL_FAR}")
                
            elif z_score < -ENTRY_THRESHOLD:
                # 价差过小,做正套(买近卖远)
                target_pos_near.set_target_volume(LOTS)
                target_pos_far.set_target_volume(-LOTS)
                position = 1
                hold_bars = 0
                print(f"[开仓] 正套:买{SYMBOL_NEAR} 卖{SYMBOL_FAR}")
        
        else:
            # 有持仓,判断平仓
            hold_bars += 1
            
            should_close = False
            close_reason = ""
            
            # 条件1:价差回归
            if position == 1 and z_score > -EXIT_THRESHOLD:
                should_close = True
                close_reason = "价差回归"
            elif position == -1 and z_score < EXIT_THRESHOLD:
                should_close = True
                close_reason = "价差回归"
            
            # 条件2:超时平仓
            if hold_bars >= MAX_HOLD_BARS:
                should_close = True
                close_reason = "持仓超时"
            
            if should_close:
                target_pos_near.set_target_volume(0)
                target_pos_far.set_target_volume(0)
                print(f"[平仓] {close_reason},持仓{hold_bars}根K线")
                position = 0
                hold_bars = 0
        
        # 显示账户状态
        print(f"  账户权益: {account.balance:.0f} 浮盈: {account.float_profit:.0f}")

4.3 代码解析

代码 说明
spread = far - near 计算价差
z_score = (spread - mean) / std 标准化价差
z_score > 2.0 价差偏大,做反套
z_score < -2.0 价差偏小,做正套
abs(z_score) < 0.5 价差回归,平仓

五、价差分析工具

python 复制代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:价差统计分析
说明:本代码仅供学习参考
"""

from tqsdk import TqApi, TqAuth
import numpy as np

# ============ 合约配置 ============
SYMBOL_NEAR = "SHFE.rb2505"
SYMBOL_FAR = "SHFE.rb2510"

api = TqApi(auth=TqAuth("快期账户", "快期密码"))

# 获取日K线
kline_near = api.get_kline_serial(SYMBOL_NEAR, 86400, 60)
kline_far = api.get_kline_serial(SYMBOL_FAR, 86400, 60)

api.wait_update()

# 计算价差
close_near = kline_near["close"].values
close_far = kline_far["close"].values
spread = close_far - close_near

# 统计分析
print("=" * 50)
print("价差统计分析")
print("=" * 50)
print(f"数据天数: {len(spread)}")
print("-" * 50)

# 基础统计
print(f"均值: {np.mean(spread):.2f}")
print(f"标准差: {np.std(spread):.2f}")
print(f"最大值: {np.max(spread):.2f}")
print(f"最小值: {np.min(spread):.2f}")
print(f"当前值: {spread[-1]:.2f}")

# 分位数
print(f"\n分位数:")
for p in [10, 25, 50, 75, 90]:
    print(f"  {p}%分位: {np.percentile(spread, p):.2f}")

# Z-Score
current_z = (spread[-1] - np.mean(spread)) / np.std(spread)
print(f"\n当前Z-Score: {current_z:.2f}")

if current_z > 2:
    print("建议: 价差偏大,可考虑反套")
elif current_z < -2:
    print("建议: 价差偏小,可考虑正套")
else:
    print("建议: 价差正常,观望")

api.close()

六、套利注意事项

6.1 合约选择

要点 说明
流动性 选择成交量大的合约
月份间隔 通常选3-6个月间隔
避免临近交割 近月合约避免进入交割月

6.2 风险提示

风险 说明 应对
价差不回归 价差持续扩大或缩小 设置止损
流动性风险 无法同时成交 选流动性好的合约
保证金风险 极端行情追保 控制仓位
交割风险 近月合约进入交割 提前移仓

七、进阶技巧

7.1 动态阈值

python 复制代码
# 根据波动率动态调整开仓阈值
def get_dynamic_threshold(spread_std, base_threshold=2.0):
    """
    波动率大时提高阈值,波动率小时降低阈值
    """
    # 假设历史标准差为50
    NORMAL_STD = 50
    ratio = spread_std / NORMAL_STD
    
    # 限制调整范围
    ratio = max(0.5, min(ratio, 2.0))
    
    return base_threshold * ratio

7.2 价差比率

python 复制代码
# 使用价差比率而非绝对价差
spread_ratio = close_far / close_near - 1

# 适用于不同价位品种的横向比较

八、总结

要点 内容
策略原理 利用价差回归获利
核心指标 Z-Score标准化价差
开仓条件 Z值超过±2倍标准差
平仓条件 Z值回归到±0.5以内
风险控制 设置止损和持仓时间限制

免责声明:本文仅供学习交流使用,不构成任何投资建议。期货交易有风险,入市需谨慎。

更多资源

相关推荐
神梦流2 小时前
ops-math 算子库的扩展能力:高精度与复数运算的硬件映射策略
服务器·数据库
极客小云2 小时前
【ComfyUI API 自动化利器:comfyui_xy Python 库使用详解】
网络·python·自动化·comfyui
让学习成为一种生活方式2 小时前
trf v4.09.1 安装与使用--生信工具42-version2
数据库
啦啦啦_99992 小时前
Redis-5-doFormatAsync()方法
数据库·redis·c#
闲人编程2 小时前
Elasticsearch搜索引擎集成指南
python·elasticsearch·搜索引擎·jenkins·索引·副本·分片
zheyutao2 小时前
字符串哈希
算法
生产队队长2 小时前
Redis:Windows环境安装Redis,并将 Redis 进程注册为服务
数据库·redis·缓存
老邓计算机毕设2 小时前
SSM找学互助系统52568(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·ssm 框架·javaweb 毕业设计
痴儿哈哈3 小时前
自动化机器学习(AutoML)库TPOT使用指南
jvm·数据库·python
A尘埃3 小时前
保险公司车险理赔欺诈检测(随机森林)
算法·随机森林·机器学习