🚀 AI 一键生成 qmt 策略代码
立即体验

qmt 平台如何实现期货跨期套利?利用 passorder 组合指令实现双边自动下单(附 Python 源码)

qmt | 发布时间: 2026/8/4
以下内容由 EasyQuant 生成。

问题描述



Title: qmt 期货跨期套利:利用 passorder 组合指令实现双边自动下单

Question: 我想在 qmt 中编写一个期货跨期套利策略,如何使用 passorder 进行组合下单?

解决方案

qmt 期货跨期套利:利用 passorder 组合指令实现双边自动下单

在期货量化交易中,**跨期套利(Calendar Spread Arbitrage)**是一种非常经典的低风险交易策略。它通过同时买入和卖出同一商品期货但不同交割月份的合约,来赚取两个合约价差(Spread)收敛或扩大的利润。

在国信证券 QMT (Quantitative Trading System) 平台上,实现跨期套利的核心难点在于双边下单的同步性。如果手动或分步发送两笔单子,极易因为市场波动产生单边踏空(Legging Risk)或严重的滑点。QMT 提供了强大的 passorder 组合交易指令,能够完美解决这一痛点。


1. 什么是 passorder 组合交易指令?

passorder 是 QMT Python API 中最核心的综合交易下单接口。针对套利和组合交易,passorder 支持特殊的 orderType(下单方式)和参数配置,允许交易员通过一篮子指令组合套利接口实现多品种同步下单。

组合套利接口特殊设置:

passorder(opType, orderType, accountID, orderCode, prType, hedgeRatio, volume, ContextInfo)
  • opType (操作类型)
    • 40:期货组合开多(买入近月,卖出远月)
    • 43:期货组合开空(卖出近月,买入远月)
    • 46:期货组合平多,优先平今
    • 47:期货组合平多,优先平昨
    • 48:期货组合平空,优先平今
    • 49:期货组合平空,优先平昨
  • orderType (下单方式)
    • 2331:组合、套利、合约价值自动套利、按组合股票数量方式下单
    • 2332:组合、套利、按合约价值自动套利、按组合股票权重方式下单
    • 2333:组合、套利、按合约价值自动套利、按账号可用方式下单
  • accountID:套利组账户,格式为 'stockAccountID, futureAccountID'(若纯期货套利,可传入期货账号)。
  • orderCode:套利合约对,格式为 '近月合约, 远月合约',例如 'IF2409.IF, IF2412.IF'
  • hedgeRatio (套利比例):通常设为 1(即 1:1 对冲),对应参数位置为 price

2. QMT 期货跨期套利策略源码示例

以下是一个基于 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

3. 跨期套利策略编写注意事项

  1. 数据补充:在回测或实盘运行前,务必通过 QMT 客户端的 操作 -> 数据管理 -> 补充数据 下载完整的期货历史日线及 Tick 数据。
  2. 主力合约换月:跨期套利通常在主力合约与次主力合约之间进行,需注意换月时的价差跳空风险,可通过 ContextInfo.get_main_contract() 动态获取主力合约。
  3. 保证金与风控:套利虽然风险较低,但双边开仓仍会占用双倍或单边减免后的保证金。请确保账户可用资金充足,避免因单边成交导致风控强平。