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

如何利用 get_dominant_future 实现商品期货主力合约的自动监控与平仓换月?

joinquant | 发布时间: 2026/7/22
以下内容由 EasyQuant 生成。

问题描述

请根据以下 SEO 主题生成完整页面内容:

Title: joinquant 期货主力合约自动移仓换月策略实现

Question: 如何利用 get_dominant_future 实现商品期货主力合约的自动监控与平仓换月?

解决方案

如何利用 get_dominant_future 实现商品期货主力合约的自动监控与平仓换月?

在商品期货量化交易中,由于期货合约具有生命周期(到期交割),长期持仓的策略必须定期进行移仓换月。聚宽(JoinQuant)平台提供了 get_dominant_future 接口,可以帮助我们实时获取某商品期货品种当前持仓量最大的主力合约。本文将详细介绍如何利用该 API 实现主力合约的自动监控与平仓换月策略。


一、 核心 API 介绍

1. get_dominant_future(underlying_symbol, date=None)

  • 作用:获取指定期货品种在指定日期(或当前回测日期)的主力合约代码。
  • 参数
    • underlying_symbol:期货品种代码,如 'RB'(螺纹钢)、'CU'(阴极铜)。
    • date:查询日期。在回测中默认不填,系统会自动获取当前回测逻辑日期。
  • 返回值:主力合约的具体代码,例如 'RB2310.XSGE'

2. 主力合约切换逻辑

聚宽平台的主力合约定义为:如果某合约持仓量连续 2 天为同一个品种中最大的,且该合约相对于当前主力合约为远期合约,则自动变成主力合约。切换不会在日内进行,而是在 T-1 日收盘后(即 T 日夜盘开始前)完成切换。


二、 移仓换月策略设计思路

  1. 初始化账户:在 initialize 中,必须将子账户类型设置为期货账户 type='futures'
  2. 每日监控:在每日开盘前(如 before_trading_start)或盘中,获取当前品种的最新主力合约。
  3. 对比持仓:检查当前持仓中的合约是否与最新的主力合约一致。
  4. 执行移仓
    • 如果持仓中的合约不再是主力合约,则平掉旧合约的仓位
    • 同时,在新主力合约上开立相同方向的等量仓位,完成移仓换月。

三、 完整策略 Python 源码

以下是一个基于聚宽 API 编写的商品期货主力合约自动移仓换月策略示例:

# 导入聚宽函数库
import jqdata

def initialize(context):
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    
    # 1. 初始化期货账户资金
    init_cash = context.portfolio.starting_cash
    set_subportfolios([SubPortfolioConfig(cash=init_cash, type='futures')])
    
    # 定义要操作的期货品种(以螺纹钢 RB 为例)
    g.underlying = 'RB'
    # 记录当前持有的具体合约
    g.current_contract = None
    
    # 2. 设置定时运行函数
    # 每天 09:30 运行主力合约监控与交易逻辑
    run_daily(market_open, time='09:30', reference_security='RB9999.XSGE')

def market_open(context):
    underlying = g.underlying
    
    # 3. 获取当前最新的主力合约
    new_dominant = get_dominant_future(underlying)
    log.info("当前最新主力合约为: %s" % new_dominant)
    
    # 如果是第一次运行,初始化主力合约
    if g.current_contract is None:
        g.current_contract = new_dominant
        # 初始开仓:买入开多 2 手
        order(g.current_contract, 2, side='long')
        log.info("初始开仓主力合约: %s, 2手" % g.current_contract)
        return

    # 4. 监控是否需要移仓换月
    if new_dominant != g.current_contract:
        log.info("检测到主力合约发生切换!旧合约: %s, 新合约: %s" % (g.current_contract, new_dominant))
        
        # 获取旧合约的持仓情况
        position = context.portfolio.long_positions.get(g.current_contract, None)
        
        if position and position.total_amount > 0:
            qty = position.total_amount
            # 1. 平掉旧合约多仓
            order_target(g.current_contract, 0, side='long')
            log.info("平仓旧合约: %s, 数量: %s" % (g.current_contract, qty))
            
            # 2. 在新主力合约上开立相同数量的多仓
            order(new_dominant, qty, side='long')
            log.info("移仓买入新合约: %s, 数量: %s" % (new_dominant, qty))
            
        # 更新全局变量
        g.current_contract = new_dominant
    else:
        log.info("主力合约未发生变化,继续持有: %s" % g.current_contract)

四、 注意事项

  1. 不可直接对主力连续合约(如 RB9999.XSGE)下单:连续合约仅用于提供拼接后的行情数据,交易时必须使用 get_dominant_future 获取具体的交割月合约(如 RB2310.XSGE)进行下单。
  2. 平今与平昨:对于上海期货交易所(XSGE)和上海国际能源交易中心(XINE),平仓时需注意区分平今仓与平昨仓。本策略中使用 order_target 默认会优先平昨仓,不足部分平今仓。
  3. 保证金预警:期货交易具有杠杆效应,移仓过程中由于先平后开,可能会短暂占用双倍保证金,请确保账户内有足够的可用资金(available_cash)以防移仓失败。