股指期货跨期套利策略

一、交易策略解释

核心思想

股指期货跨期套利策略基于价差均值回归原理,通过统计分析不同到期月份合约之间的价差变动规律,在价差偏离合理范围时建立套利头寸,待价差回归时获利了结。 这是一种相对低风险的统计套利方法,不依赖市场单边方向,专注于捕捉合约间价差的波动机会。

理论基础

  • 均值回归理论:同一品种不同月份合约的价差在长期内会围绕一个均值上下波动,当价差偏离均值过大时,存在回归的趋势
  • 正态分布假设:价差的波动通常符合或接近正态分布,通过计算标准差可以确定价差偏离程度
  • 基差收敛原理:随着合约临近交割,远月与近月合约的价差会逐渐收敛,提供了价差回归的内在驱动力

策略适用场景

  • 最佳适用
    • 震荡整理市场,价差波动规律性强
    • 主力合约与次主力合约交易组合
    • 非交割月的常规交易期
    • 流动性充足的股指期货品种
  • 不宜使用
    • 极端单边市场,尤其是市场恐慌或剧烈上涨时期
    • 交割月最后一周
    • 重大政策或经济数据发布前后
    • 合约流动性严重不足的情况

二、天勤介绍

天勤平台概述

天勤(TqSdk)是一个由信易科技开发的开源量化交易系统,为期货、期权等衍生品交易提供专业的量化交易解决方案。平台具有以下特 点:

  • 丰富的行情数据 提供所有可交易合约的全部Tick和K线数据,基于内存数据库实现零延迟访问。
  • 一站式的解决方案 从历史数据分析到实盘交易的完整工具链,打通开发、回测、模拟到实盘的全流程。
  • 专业的技术支持 近百个技术指标源码,深度集成pandas和numpy,采用单线程异步模型保证性能。

策略开发流程

  • 环境准备
    • 安装Python环境(推荐Python 3.6或以上版本)
    • 安装tqsdk包:pip install tqsdk
    • 注册天勤账户获取访问密钥
  • 数据准备
    • 订阅近月与远月合约行情
    • 获取历史K线或者Tick数据(用于分析与行情推进)
  • 策略编写
    • 设计信号生成逻辑(基于价差、均值和标准差)
    • 编写交易执行模块(开仓、平仓逻辑)
    • 实现风险控制措施(止损、资金管理)
  • 回测验证
    • 设置回测时间区间和初始资金
    • 运行策略获取回测结果
    • 分析绩效指标(胜率、收益率、夏普率等)
  • 策略优化
    • 调整参数(标准差倍数、窗口大小等)
    • 添加过滤条件(成交量、波动率等)
    • 完善风险控制机制

三、天勤实现策略

策略原理

本策略通过统计方法计算近月合约与远月合约价差的均值和标准差,设定价差的合理波动区间(均值±K倍标准差)。 当价差突破上边界时,做空价差(卖近买远);当价差突破下边界时,做多价差(买近卖远);当价差回归至均值时平仓获利。

交易逻辑

  • 开仓信号:
    • 价差 > 均值 + k * 标准差: 做空价差(卖近买远)
    • 价差 < 均值 - k * 标准差: 做多价差(买近卖远)
  • 平仓信号:
    • 多价差持仓: 当价差回升至均值时平仓获利
    • 空价差持仓: 当价差下降至均值时平仓获利
  • 止损机制:
    • 当亏损超过2倍标准差时触发止损
    • 可以根据风险偏好调整止损倍数

回测

回测初始设置

  • 测试周期: 2020 年 12 月 21 日至 2021 年 1 月 15 日
  • 交易品种: CFFEX.IH2101(上证50指数期货2101合约)与CFFEX.IH2102(2102合约)的跨期套利
  • 初始资金: 1000万元
  • 交易手数: 每次开仓20手
  • 策略参数: k=2(标准差倍数), window=80(计算窗口)

回测结果

上述回测累计收益走势图

完整代码示例

#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = "Chaos"

from datetime import date

import numpy as np
from tqsdk import TqApi, TqAuth, TqBacktest, TargetPosTask, BacktestFinished

# 参数设置
NEAR_CONTRACT = "CFFEX.IH2101"  # 近月合约
FAR_CONTRACT = "CFFEX.IH2102"  # 远月合约
K = 2  # 标准差倍数
WINDOW = 80  # 计算窗口
LOTS = 20  # 交易手数
START_DATE = date(2020, 12, 21)  # 回测开始日期
END_DATE = date(2021, 1, 15)  # 回测结束日期

# 创建API实例
api = TqApi(backtest=TqBacktest(start_dt=START_DATE, end_dt=END_DATE),
            auth=TqAuth("快期账号", "快期密码"))

# 订阅行情
near_quote = api.get_quote(NEAR_CONTRACT)
far_quote = api.get_quote(FAR_CONTRACT)
near_klines = api.get_kline_serial(NEAR_CONTRACT, 15 * 60, WINDOW * 2)  # 15分钟K线
far_klines = api.get_kline_serial(FAR_CONTRACT, 15 * 60, WINDOW * 2)

# 创建目标持仓任务
near_pos = TargetPosTask(api, NEAR_CONTRACT)
far_pos = TargetPosTask(api, FAR_CONTRACT)

# 持仓状态: 0-无持仓, 1-多价差(买近卖远), -1-空价差(卖近买远)
position_state = 0

print(f"策略启动: {NEAR_CONTRACT}-{FAR_CONTRACT} 跨期套利")
print(f"参数设置: K={K}倍标准差, 窗口={WINDOW}, 交易手数={LOTS}手")

try:
    while True:
        api.wait_update()

        # 检查K线是否更新
        if api.is_changing(near_klines) or api.is_changing(far_klines):
            # 确保有足够的数据
            if len(near_klines) < WINDOW or len(far_klines) < WINDOW:
                continue

            # 计算价差指标
            near_close = near_klines.close.iloc[-WINDOW:]
            far_close = far_klines.close.iloc[-WINDOW:]
            spread = near_close - far_close

            # 计算均值和标准差
            mean = np.mean(spread)
            std = np.std(spread)
            current_spread = near_quote.last_price - far_quote.last_price

            # 计算上下边界
            upper_bound = mean + K * std
            lower_bound = mean - K * std

            print(f"价差: {current_spread:.2f}, 均值: {mean:.2f}, "
                  f"上界: {upper_bound:.2f}, 下界: {lower_bound:.2f}")

            # 交易逻辑
            if position_state == 0:  # 无持仓状态
                if current_spread > upper_bound:  # 做空价差(卖近买远)
                    near_pos.set_target_volume(-LOTS)
                    far_pos.set_target_volume(LOTS)
                    position_state = -1
                    print(f"开仓: 卖出{LOTS}{NEAR_CONTRACT}, 买入{LOTS}{FAR_CONTRACT}")

                elif current_spread < lower_bound:  # 做多价差(买近卖远)
                    near_pos.set_target_volume(LOTS)
                    far_pos.set_target_volume(-LOTS)
                    position_state = 1
                    print(f"开仓: 买入{LOTS}{NEAR_CONTRACT}, 卖出{LOTS}{FAR_CONTRACT}")

            elif position_state == 1:  # 持有多价差
                if current_spread >= mean:  # 平仓获利
                    near_pos.set_target_volume(0)
                    far_pos.set_target_volume(0)
                    position_state = 0
                    print("平仓: 价差回到均值,平仓获利")

            elif position_state == -1:  # 持有空价差
                if current_spread <= mean:  # 平仓获利
                    near_pos.set_target_volume(0)
                    far_pos.set_target_volume(0)
                    position_state = 0
                    print("平仓: 价差回到均值,平仓获利")

except BacktestFinished as e:
    api.close()
    print("回测结束")

参考:华创期货