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

joinquant 股期混合策略:利用 set_subportfolios 实现多资产仓位隔离与资金管理

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

问题描述

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

Title: joinquant 股期混合策略:利用 set_subportfolios 实现多资产仓位隔离

Question: 如何在 joinquant 中同时交易股票和期货并对不同账户资金进行独立管理?

解决方案

joinquant 股期混合策略:利用 set_subportfolios 实现多资产仓位隔离

在 JoinQuant(聚宽)量化平台上,默认的初始账户仓位类型为股票账户(type='stock'),无法直接进行期货交易或融资融券操作。若需同时交易股票与期货,必须在策略初始化阶段通过 set_subportfolios 函数配置多个子账户(SubPortfolio),以实现资产隔离与独立的资金风险控制。


1. 核心 API 介绍

set_subportfolios

用于初始化或修改策略的子账户配置。注意:该函数只能在 initialize(context) 中调用,且所有子账户初始资金(cash)之和必须等于策略的总初始资金 context.portfolio.starting_cash

set_subportfolios([SubPortfolioConfig(cash, type), ...])
  • cash: 设定该子账户分配的初始资金。
  • type: 账户类型,支持:
    • 'stock': 股票与场内基金账户
    • 'futures': 商品期货与股指期货账户
    • 'index_futures': 金融期货账户
    • 'stock_margin': 融资融券账户

transfer_cash

用于在运行过程中动态划转不同子账户间的资金。

transfer_cash(from_pindex=0, to_pindex=1, cash=50000)

2. 股期混合策略多仓位下单规则

在包含多个子账户时,下单函数(如 orderorder_targetorder_value 等)需要指定 pindex 参数:

  • pindex=0:代表第 1 个子账户(SubPortfolio[0])
  • pindex=1:代表第 2 个子账户(SubPortfolio[1])

若未指定 pindex,系统默认使用 pindex=0。如果尝试在 type='stock' 的账户中买入期货,订单将会创建失败。


3. 完整策略示例源码

以下策略演示了如何建立股票账户(子账户 0)与期货账户(子账户 1),并实现定期调仓与独立下单。

import jqdata
from jqdata import *

def initialize(context):
    # 开启动态复权模式
    set_option('use_real_price', True)
    # 设置基准
    set_benchmark('000300.XSHG')
    
    # 获取初始资金并平均分配给股票和期货账户
    total_cash = context.portfolio.starting_cash
    half_cash = total_cash / 2.0
    
    # 配置 2 个子账户:pindex=0 为股票账户,pindex=1 为期货账户
    set_subportfolios([
        SubPortfolioConfig(cash=half_cash, type='stock'),
        SubPortfolioConfig(cash=half_cash, type='futures')
    ])
    
    # 设定股票费率
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    # 设定商品期货保证金比例
    set_option('futures_margin_rate', 0.10)
    
    # 设定全局变量
    g.stock_code = '000001.XSHE' # 平安银行
    g.future_symbol = 'RB'      # 螺纹钢品种
    
    # 每日 09:30 运行交易逻辑
    run_daily(market_open, time='09:30', reference_security='000300.XSHG')

def market_open(context):
    # ---------------- 1. 股票账户操作 (pindex=0) ----------------
    stock_cash = context.subportfolios[0].available_cash
    # 若股票子账户有现金,则买入平安银行
    if stock_cash > 5000:
        order_value(g.stock_code, stock_cash, pindex=0)
        log.info("股票账户买入: %s" % g.stock_code)
        
    # ---------------- 2. 期货账户操作 (pindex=1) ----------------
    # 获取螺纹钢当前主力合约
    dominant_future = get_dominant_future(g.future_symbol, context.current_dt.date())
    if dominant_future:
        # 获取期货账户持仓
        positions = context.subportfolios[1].long_positions
        if dominant_future not in positions or positions[dominant_future].total_amount == 0:
            # 开一手多单
            order(dominant_future, 1, side='long', pindex=1)
            log.info("期货账户开多仓: %s" % dominant_future)

def after_trading_end(context):
    log.info("股票账户总资产: %.2f" % context.subportfolios[0].total_value)
    log.info("期货账户总资产: %.2f" % context.subportfolios[1].total_value)

4. 常见问题与注意事项

  1. 下单失败(返回 None)
    • 请检查是否将期货订单发送到了 type='stock' 的子账户(pindex 错误)。
    • 请确保交易的标的代码正确,且对应品种在当前交易时间可交易。
  2. 期货主力合约无法直接下单
    • 主力连续合约(如 RB9999.XSGE)仅用于行情获取,不可直接下单,必须先通过 get_dominant_future('RB') 换算为具体合约代码。
  3. 账户风险预警
    • 可通过 context.subportfolios[i].is_dangerous(margin_rate) 实时监控期货子账户保证金比例,防止因亏损被强平。