热卷–不锈钢套利(成材对冲)策略
一、交易策略解释
核心思想
热卷-不锈钢套利的核心在于监控和交易两者之间的“相对价值”或“价格比率”。热轧卷板(HC)和不锈钢(SS)虽然在化学成分、性能和主要用途上有所区别,但在某些工业应用领域(如部分结构件、容器、管道、家电、厨具等)存在一定的选择空间或间接的替代可能。当两者的价格比率偏离其历史常规水平时,可能预示着市场对两者相对价值的短期错估或供需关系的暂时失衡。
- 热卷-不锈钢相对价值 (HC-SS Relative Value or Price Ratio): 相对价值 = (热卷期货价值 × 热卷权重) - (不锈钢期货价值 × 不锈钢权重),其中权重因子旨在调整两者在比较中的相对重要性或模拟某种应用中的成本对比。
核心思想是:
- 这个相对价值会受到各自供需基本面(钢铁行业与不锈钢行业自身的产能、产量、库存、进出口、环保政策等)、上游原料成本(铁矿石、焦炭、镍、铬铁等)、宏观经济状况、以及下游主要消费行业(如建筑、汽车、机械制造、家电等)景气度的综合影响。策略通过计算该相对价值(或比价)的标准化得分(Z-score)来衡量其偏离历史均值的程度。
- 预期相对价值扩大: 当该相对价值(或比价)的Z-score显著为负,表明当前热卷相对于不锈钢的价格(或价值)远低于其历史平均关系。策略预期此关系会向均值回升,因此会买入热卷期货,同时卖出相应配比的不锈钢期货。
- 预期相对价值缩小: 当该相对价值(或比价)的Z-score显著为正,表明当前热卷相对于不锈钢的价格(或价值)远高于其历史平均关系。策略预期此关系会向均值回落,因此会卖出热卷期货,同时买入相应配比的不锈钢期货。
- 该策略的平仓逻辑则基于相对价值(或比价的Z-score)向其历史均值区域回归。
理论基础
-
部分替代与关联性: 虽然不完全等同,但在某些对耐腐蚀性要求不高或可以通过表面处理达到要求的领域,成本较低的碳钢(如热卷)可能在一定程度上与不锈钢形成竞争或影响不锈钢的定价。反之,在某些追求更高性能或特定外观的场合,不锈钢是首选。它们共同服务于广泛的工业制造领域,因此其需求会受到共同的宏观经济和下游行业景气度的影响。
-
供需基本面的驱动:
- 热卷端 (HC): 主要受钢铁行业高炉和轧线开工率、铁矿石和焦炭等原料价格、房地产和基建投资、汽车和家电等制造业需求、库存水平、以及环保限产政策等影响。
- 不锈钢端 (SS): 主要受不锈钢厂(尤其是使用镍铁、铬铁的一体化钢厂和使用废不锈钢的电炉厂)的开工率、镍和铬等核心合金原料价格波动、国内外不锈钢库存、下游特定行业(如高端厨具、医疗器械、化工设备、沿海建筑等)的需求、以及反倾销等贸易政策影响。
-
均值回归特性 (Mean Reversion of Relative Value/Price Ratio): 由于两者在工业应用上的部分关联性和共同的需求驱动因素,它们的相对价值(或价格比率)在一定周期内可能表现出围绕某个历史均值波动的特性。当比价偏离过大时,市场参与者的采购决策调整、钢厂排产计划的微调或宏观因素的共同作用可能促使其向历史关系回归。
-
下游消费行业景气度: 建筑业(钢结构、管道)、制造业(汽车、机械、家电、容器)是热卷和不锈钢的共同主要下游。这些行业的整体需求变化会同时影响两者的价格,但影响的幅度和节奏可能不同,从而导致其比价的波动。策略会间接跟踪这些行业的景气度变化如何反映在期货价格的相对强弱上。
策略适用场景
- 热卷-不锈钢相对价值(或比价)显著偏离: 当计算出的相对价值(或比价)的Z-score突破预设的阈值时,视为潜在的交易信号。
- 预期均值回归: 策略的盈利平仓通常依赖于该相对关系最终向其历史均值区域回归的预期。
- 宏观及行业分析辅助: 结合对整体宏观经济、钢铁行业、不锈钢行业以及主要下游消费行业(建筑、制造)的分析。例如,如果Z-score发出信号,但基本面显示某一品种因特定政策或事件(如针对性的出口退税调整)导致其供需结构发生长期变化,则可能需要调整对均值回归的预期。
- 流动性充足: 策略涉及上海期货交易所(SHFE)的热轧卷板期货(SHFE.HC)和不锈钢期货(SHFE.SS),需要保证各合约均有良好的流动性。
二、天勤介绍
天勤平台概述
天勤(TqSdk)是一个由信易科技开发的开源量化交易系统,为期货、期权等衍生品交易提供专业的量化交易解决方案。平台具有以下特 点:
- 丰富的行情数据: 提供所有可交易合约的全部Tick和K线数据,基于内存数据库实现零延迟访问。
- 一站式的解决方案: 从历史数据分析到实盘交易的完整工具链,打通开发、回测、模拟到实盘的全流程。
- 专业的技术支持: 近百个技术指标源码,深度集成pandas和numpy,采用单线程异步模型保证性能。
策略开发流程
- 环境准备
- 安装Python环境(推荐Python 3.6或以上版本)
- 安装tqsdk包:pip install tqsdk
- 注册天勤账户获取访问密钥
- 数据准备
- 订阅近月与远月合约行情
- 获取历史K线或者Tick数据(用于分析与行情推进)
- 策略编写
- 设计信号生成逻辑(基于价差、均值和标准差)
- 编写交易执行模块(开仓、平仓逻辑)
- 实现风险控制措施(止损、资金管理)
- 回测验证
- 设置回测时间区间和初始资金
- 运行策略获取回测结果
- 分析绩效指标(胜率、收益率、夏普率等)
- 策略优化
- 调整参数(标准差倍数、窗口大小等)
- 添加过滤条件(成交量、波动率等)
- 完善风险控制机制
三、天勤实现策略
策略原理
核心价差定义与计算:热卷对不锈钢的“合约价值比率”:
该策略的核心是追踪一个经过特定合约参数和预设权重调整后的热卷期货合约价值与不锈钢期货合约价值之间的比率。这个“合约价值比率”通过以下方式计算得出:
- 为热卷(HC)和不锈钢(SS)期货分别设定一个“权重因子”(脚本中热卷的HC_RATIO为1,不锈钢的SS_RATIO为1)。这些因子代表在计算比率时,各自合约价值的取用倍数。
- 计算单手热卷合约的当前总价值:热卷单手合约价值 = 热卷期货最新价格 × 热卷合约乘数。
- 计算单手不锈钢合约的当前总价值:不锈钢单手合约价值 = 不锈钢期货最新价格 × 不锈钢合约乘数。
- 热卷-不锈钢合约价值比率 被定义为:(热卷单手合约价值 × 热卷权重因子) / (不锈钢单手合约价值 × 不锈钢权重因子)。 若不锈钢的调整后合约价值为零(例如价格或乘数为零的极端情况),则此比率特殊处理为零,以避免计算错误。
指标构建:
策略采用标准化得分(Z-score) 来衡量当前计算出的“热卷-不锈钢合约价值比率”与其近期历史水平的偏离程度。
- 历史比率序列: 收集特定热卷和不锈钢期货合约在过去一段固定交易日(例如30天,即脚本中的LOOKBACK_DAYS)内的每日收盘价。基于这些价格和上述“合约价值比率”的计算方法,得到一个每日“合约价值比率”的历史序列。
- 计算历史均值: 对这个历史比率序列计算其算术平均值。
- 计算历史标准差: 对同一个历史比率序列计算其标准差。
- 计算标准化得分: 用最新的每日收盘价计算出当前的“合约价值比率”,然后通过以下公式得到其标准化得分: 标准化得分 = (当前合约价值比率 - 历史均值) / 历史标准差
交易逻辑
开仓信号 (入场):
-
预期“合约价值比率”从高位回落:
- 信号: 当计算出的“标准化得分”显著高于一个预设的正阈值(例如,大于2.0)。这表明当前的“热卷合约价值”相对于“不锈钢合约价值”的比率远高于其历史平均水平。
- 操作: 策略预期此高比率会向均值回落。因此,卖出预定数量的热卷期货,同时买入按上述方法计算出的不锈钢期货手数。
-
预期“合约价值比率”从低位回升:
- 信号: 当计算出的“标准化得分”显著低于一个预设的负阈值(例如,小于负2.0)。这表明当前的“热卷合约价值”相对于“不锈钢合约价值”的比率远低于其历史平均水平。
- 操作: 策略预期此低比率会向均值回升。因此,买入预定数量的热卷期货,同时卖出按上述方法计算出的不锈钢期货手数。
平仓信号:
- 信号: 当“标准化得分”的绝对值回落到一个较小的预设阈值以内(例如,小于0.5)。这表示之前显著偏离的“合约价值比率”已经回归到接近其历史平均的水平。
- 操作: 将所有持有的期货头寸全部平掉(即目标持仓设为零)。
回测
回测初始设置
- 测试周期: 2024 年 10 月 1 日 - 2025 年 1 月 1 日
- 交易品种: SHFE.hc2507/SHFE.ss2507
- 初始资金: 1000万元
回测结果

上述回测累计收益走势图

完整代码示例
from tqsdk import TqApi, TqBacktest, TargetPosTask, TqAuth, BacktestFinished
import numpy as np
from datetime import date
# === 用户参数 ===
HC = "SHFE.hc2507" # 热轧卷板主力合约
SS = "SHFE.ss2507" # 不锈钢主力合约
START_DATE = date(2024, 10, 1)
END_DATE = date(2025, 1, 1)
LOOKBACK_DAYS = 30 # 历史窗口
STD_THRESHOLD = 2.0 # 开仓Z-score阈值
CLOSE_THRESHOLD = 0.5 # 平仓Z-score阈值
ORDER_VOLUME = 200 # 热卷下单手数
HC_RATIO = 1 # 热卷权重
SS_RATIO = 1 # 不锈钢权重
api = TqApi(backtest=TqBacktest(start_dt=START_DATE, end_dt=END_DATE),auth=TqAuth("快期账号","快期密码"))
hc_quote = api.get_quote(HC)
ss_quote = api.get_quote(SS)
hc_klines = api.get_kline_serial(HC, 60*60*24, LOOKBACK_DAYS)
ss_klines = api.get_kline_serial(SS, 60*60*24, LOOKBACK_DAYS)
hc_pos = TargetPosTask(api, HC)
ss_pos = TargetPosTask(api, SS)
in_position = False
print(f"热卷-不锈钢套利策略启动,监控合约: {HC}, {SS}")
try:
while True:
api.wait_update()
if api.is_changing(hc_klines) or api.is_changing(ss_klines):
# 计算历史相对价值(比价)
ratios = []
for i in range(len(hc_klines.close) - 1):
hc_value = hc_klines.close.iloc[i] * hc_quote.volume_multiple * HC_RATIO
ss_value = ss_klines.close.iloc[i] * ss_quote.volume_multiple * SS_RATIO
# 这里用比价,也可以用价差
ratio = hc_value / ss_value if ss_value != 0 else 0
ratios.append(ratio)
mean_ratio = np.mean(ratios)
std_ratio = np.std(ratios)
# 当前比价
hc_value = hc_klines.close.iloc[-1] * hc_quote.volume_multiple * HC_RATIO
ss_value = ss_klines.close.iloc[-1] * ss_quote.volume_multiple * SS_RATIO
current_ratio = hc_value / ss_value if ss_value != 0 else 0
z_score = (current_ratio - mean_ratio) / std_ratio
print(f"当前热卷/不锈钢比价: {current_ratio:.4f}, Z-score: {z_score:.2f}")
# 计算不锈钢下单手数(按比例)
ss_volume = int(ORDER_VOLUME * SS_RATIO / HC_RATIO)
if ss_volume < 1:
ss_volume = 1
# === 交易信号判断 ===
if not in_position:
if z_score > STD_THRESHOLD:
# 比价偏高,预期回落:卖出热卷,买入不锈钢
print(f"比价偏高: 卖出热卷{ORDER_VOLUME}手,买入不锈钢{ss_volume}手")
hc_pos.set_target_volume(-ORDER_VOLUME)
ss_pos.set_target_volume(ss_volume)
in_position = True
elif z_score < -STD_THRESHOLD:
# 比价偏低,预期回升:买入热卷,卖出不锈钢
print(f"比价偏低: 买入热卷{ORDER_VOLUME}手,卖出不锈钢{ss_volume}手")
hc_pos.set_target_volume(ORDER_VOLUME)
ss_pos.set_target_volume(-ss_volume)
in_position = True
else:
# 平仓条件
if abs(z_score) < CLOSE_THRESHOLD:
print("比价回归,平仓所有头寸")
hc_pos.set_target_volume(0)
ss_pos.set_target_volume(0)
in_position = False
except BacktestFinished as e:
print("回测结束")
api.close()