3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在期货量化交易中,**跨期套利(Calendar Spread Arbitrage)**是一种非常经典的低风险交易策略。它通过同时买入和卖出同一商品期货但不同交割月份的合约,来赚取两个合约价差(Spread)收敛或扩大的利润。
在国信证券 QMT (Quantitative Trading System) 平台上,实现跨期套利的核心难点在于双边下单的同步性。如果手动或分步发送两笔单子,极易因为市场波动产生单边踏空(Legging Risk)或严重的滑点。QMT 提供了强大的 passorder 组合交易指令,能够完美解决这一痛点。
passorder 是 QMT Python API 中最核心的综合交易下单接口。针对套利和组合交易,passorder 支持特殊的 orderType(下单方式)和参数配置,允许交易员通过一篮子指令或组合套利接口实现多品种同步下单。
passorder(opType, orderType, accountID, orderCode, prType, hedgeRatio, volume, ContextInfo)
40:期货组合开多(买入近月,卖出远月)43:期货组合开空(卖出近月,买入远月)46:期货组合平多,优先平今47:期货组合平多,优先平昨48:期货组合平空,优先平今49:期货组合平空,优先平昨2331:组合、套利、合约价值自动套利、按组合股票数量方式下单2332:组合、套利、按合约价值自动套利、按组合股票权重方式下单2333:组合、套利、按合约价值自动套利、按账号可用方式下单'stockAccountID, futureAccountID'(若纯期货套利,可传入期货账号)。'近月合约, 远月合约',例如 'IF2409.IF, IF2412.IF'。1(即 1:1 对冲),对应参数位置为 price。以下是一个基于 QMT 编写的简单跨期套利策略。策略监控沪深300股指期货(IF)近月与远月合约的价差,当价差偏离均值时,利用 passorder 发送组合套利指令。
#encoding:gbk
import numpy as np
def init(ContextInfo):
# 1. 设定套利合约对(近月与远月)
ContextInfo.near_contract = 'IF2409.IF'
ContextInfo.far_contract = 'IF2412.IF'
ContextInfo.set_universe([ContextInfo.near_contract, ContextInfo.far_contract])
# 2. 设定交易账号
ContextInfo.account_id = '123456' # 请替换为您的真实期货资金账号
ContextInfo.set_account(ContextInfo.account_id)
# 3. 策略参数设置
ContextInfo.trade_size = 1 # 每次套利下单手数
ContextInfo.entry_threshold = 30 # 开仓价差阈值
ContextInfo.exit_threshold = 5 # 平仓价差阈值
ContextInfo.is_position = 0 # 0: 空仓, 1: 持有正套(买近卖远), -1: 持有反套(卖近买远)
def handlebar(ContextInfo):
# 获取最新行情数据
near_quote = ContextInfo.get_full_tick([ContextInfo.near_contract])
far_quote = ContextInfo.get_full_tick([ContextInfo.far_contract])
if not near_quote or not far_quote:
return
near_price = near_quote[ContextInfo.near_contract]['lastPrice']
far_price = far_quote[ContextInfo.far_contract]['lastPrice']
# 计算当前价差 (近月 - 远月)
current_spread = near_price - far_price
print(f"当前时间戳: {ContextInfo.get_tick_timetag()} | 近月价格: {near_price} | 远月价格: {far_price} | 当前价差: {current_spread}")
# 组合下单代码与合约对定义
order_code = f"{ContextInfo.near_contract},{ContextInfo.far_contract}"
# 交易逻辑判断
if ContextInfo.is_position == 0:
# 价差过大,做空价差(卖近买远 -> 反套)
if current_spread > ContextInfo.entry_threshold:
print("【信号触发】价差过大,执行反向套利(开空组合)")
# opType=43: 期货组合开空, orderType=2331: 自动套利按数量下单
passorder(43, 2331, ContextInfo.account_id, order_code, 5, 1.0, ContextInfo.trade_size, 'Spread_Arbitrage', 1, ContextInfo)
ContextInfo.is_position = -1
# 价差过小,做多价差(买近卖远 -> 正套)
elif current_spread < -ContextInfo.entry_threshold:
print("【信号触发】价差过小,执行正向套利(开多组合)")
# opType=40: 期货组合开多
passorder(40, 2331, ContextInfo.account_id, order_code, 5, 1.0, ContextInfo.trade_size, 'Spread_Arbitrage', 1, ContextInfo)
ContextInfo.is_position = 1
elif ContextInfo.is_position == 1: # 持有正套,等待价差回归平仓
if current_spread >= -ContextInfo.exit_threshold:
print("【信号触发】正套价差回归,执行平仓")
# opType=46: 期货组合平多(优先平今)
passorder(46, 2331, ContextInfo.account_id, order_code, 5, 1.0, ContextInfo.trade_size, 'Spread_Arbitrage', 1, ContextInfo)
ContextInfo.is_position = 0
elif ContextInfo.is_position == -1: # 持有反套,等待价差回归平仓
if current_spread <= ContextInfo.exit_threshold:
print("【信号触发】反套价差回归,执行平仓")
# opType=48: 期货组合平空(优先平今)
passorder(48, 2331, ContextInfo.account_id, order_code, 5, 1.0, ContextInfo.trade_size, 'Spread_Arbitrage', 1, ContextInfo)
ContextInfo.is_position = 0
操作 -> 数据管理 -> 补充数据 下载完整的期货历史日线及 Tick 数据。ContextInfo.get_main_contract() 动态获取主力合约。