🚀 AI 一键生成 joinquant 策略代码

如何在 JoinQuant 中同时管理股票和期货两个独立的子账户?

joinquant | 发布时间: 2025/11/25
以下内容由 EasyQuant 生成。

问题描述

我希望将资金分开管理,一部分做股票,一部分做期货,如何设置?

解决方案

在聚宽(JoinQuant)中,要将资金分开管理(一部分做股票,一部分做期货),需要在 initialize 函数中使用 set_subportfolios API 来初始化多个子账户(SubPortfolios)。

通过 SubPortfolioConfig 可以指定每个子账户的资金量和账户类型(股票或期货)。

以下是具体的设置方法和代码示例:

核心步骤说明

  1. 初始化子账户:在 initialize 中调用 set_subportfolios
  2. 指定类型
    • 股票账户类型为 'stock'
    • 期货账户类型为 'futures'(包含商品期货和股指期货)或 'index_futures'(仅金融期货)。
  3. 下单指定账户:在调用 order 系列函数时,通过参数 pindex 指定使用哪个子账户(索引从 0 开始)。

策略代码示例

# -*- coding: utf-8 -*-
from jqdata import *

def initialize(context):
    # 1. 设定基准(通常设为沪深300)
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    
    # 2. 获取回测设置的总初始资金
    total_cash = context.portfolio.starting_cash
    
    # 3. 规划资金分配,例如:60%做股票,40%做期货
    stock_cash = total_cash * 0.6
    futures_cash = total_cash * 0.4
    
    # 4. 设置子账户 (SubPortfolios)
    # pindex=0: 股票账户
    # pindex=1: 期货账户
    set_subportfolios([
        SubPortfolioConfig(cash=stock_cash, type='stock'),
        SubPortfolioConfig(cash=futures_cash, type='futures')
    ])
    
    # 设置股票交易手续费
    set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
    # 设置期货交易手续费 (此处以所有期货为例)
    set_order_cost(OrderCost(open_tax=0, close_tax=0, open_commission=0.000023, close_commission=0.000023, close_today_commission=0.0023, min_commission=0), type='futures')

    # 每天开盘时运行
    run_daily(market_open, time='open')

def market_open(context):
    # --- 股票操作示例 (使用 pindex=0) ---
    # 获取股票账户的可用资金
    stock_subportfolio = context.subportfolios[0]
    stock_available_cash = stock_subportfolio.available_cash
    
    # 示例:买入平安银行
    if stock_available_cash > 2000:
        # 注意:pindex=0 是默认值,写上是为了代码清晰
        order('000001.XSHE', 100, pindex=0)
        log.info("股票账户下单买入平安银行")

    # --- 期货操作示例 (使用 pindex=1) ---
    # 获取期货账户的可用资金
    futures_subportfolio = context.subportfolios[1]
    futures_available_cash = futures_subportfolio.available_cash
    
    # 示例:获取螺纹钢主力合约
    rb_code = get_dominant_future('RB')
    
    if rb_code and futures_available_cash > 10000:
        # 注意:期货下单必须指定 pindex=1,否则会默认使用股票账户导致报错
        # side='long' 做多, side='short' 做空
        order(rb_code, 1, side='long', pindex=1)
        log.info("期货账户下单做多螺纹钢: %s" % rb_code)

    # 打印两个账户的资金情况
    log.info("股票账户总资产: %.2f" % stock_subportfolio.total_value)
    log.info("期货账户总资产: %.2f" % futures_subportfolio.total_value)

关键点总结

  1. 资金总和SubPortfolioConfig 中分配的 cash 之和必须等于回测设置的初始资金(context.portfolio.starting_cash)。
  2. pindex 参数
    • pindex 对应 set_subportfolios 列表中定义的顺序。
    • 在上面的代码中,列表第一个是股票,所以股票操作用 pindex=0
    • 列表第二个是期货,所以期货操作用 pindex=1
    • 注意:如果期货下单忘记写 pindex=1,系统会默认使用 pindex=0(股票账户),这会导致“账户类型错误”或“标的不存在”的报错。
  3. 数据查询
    • 查询总资产:context.portfolio.total_value
    • 查询股票子账户资产:context.subportfolios[0].total_value
    • 查询期货子账户资产:context.subportfolios[1].total_value