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

如何在 joinquant 中基于 RiskParity 模型构建风险平价组合策略?

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

问题描述

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

Title: joinquant 资产配置:基于 RiskParity 模型构建风险平价组合策略

Question: 请问如何在 joinquant 中调用 portfolio_optimizer 实现多资产的风险平价配置?

解决方案

在 joinquant 中基于 RiskParity 模型构建风险平价策略

风险平价(Risk Parity)是一种经典的资产配置框架,旨在让投资组合中各资产或资产类别所贡献的风险(方差)相等,从而避免资产权重集中于高波动资产。在 joinquant 聚宽量化平台中,我们可以通过内置的 jqlib.optimizer 优化器模块,结合 portfolio_optimizerRiskParity 目标函数快速实现这一模型。


1. 核心 API 介绍

要在 joinquant 中构建风险平价组合,主要使用以下模块和接口:

  • 优化模型导入from jqlib.optimizer import *
  • 优化函数portfolio_optimizer(date, securities, target, constraints, bounds, ...)
  • 目标函数RiskParity(count=250, risk_budget=None)
    • count: 历史计算窗口天数,默认为 250 个交易日。
    • risk_budget: 资产风险预算,为 None 时表示各个标的风险贡献相等。
  • 约束条件
    • MarketConstraint(market_type, low, high):按标的类型(如股票 stock、基金 etf)限制权重。
    • Bound(low, high):限制单只标的的权重边界。

2. 策略构建逻辑与完整代码

以下策略在每月初运行,精选上证50成分股与多只代表性 ETF(如股票型、债券型、大宗商品类 ETF),并利用 RiskParity 计算出最优配置权重进行调仓。

# 导入 JoinQuant 基础库及优化器模块
import pandas as pd
from jqdata import *
from jqlib.optimizer import *

def initialize(context):
    # 设定基准为沪深300指数
    set_benchmark('000300.XSHG')
    # 开启动态复权(真实价格模式)
    set_option('use_real_price', True)
    
    # 设置股票与基金交易手续费
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, 
                            close_commission=0.0003, min_commission=5), type='stock')
    
    # 设置定时调仓任务:每月第一个交易日开盘前选股,开盘时执行调仓
    run_monthly(before_market_open, monthday=1, time='09:00', reference_security='000300.XSHG')
    run_monthly(market_open, monthday=1, time='09:30', reference_security='000300.XSHG')

def before_market_open(context):
    # 选取组合标的股票池:部分上证50成分股 + 多元化ETF
    etf_list = [
        '159902.XSHE', # 创业板ETF
        '510050.XSHG', # 上证50ETF
        '511010.XSHG', # 国债ETF
        '518880.XSHG'  # 黄金ETF
    ]
    # 取上证50后10只成分股加上ETF组成拟配置资产池
    stocks = list(get_index_stocks('000016.XSHG')[-10:])
    g.buy_list = stocks + etf_list

def market_open(context):
    # 1. 卖出不再资产池中的持仓
    sell_list = set(context.portfolio.positions.keys()) - set(g.buy_list)
    for stock in sell_list:
        order_target_value(stock, 0)
        
    # 2. 调用 portfolio_optimizer 进行风险平价模型计算
    # 设置 RiskParity 优化,限制单只标的权重不超过 15%
    optimized_weights = portfolio_optimizer(
        date=context.previous_date,
        securities=g.buy_list,
        target=RiskParity(count=250, risk_budget=None),
        constraints=[
            MarketConstraint('stock', low=0.0, high=0.8),
            MarketConstraint('etf', low=0.0, high=0.5)
        ],
        bounds=[Bound(0.0, 0.15)],
        default_port_weight_range=[0.0, 1.0],
        ftol=1e-09,
        return_none_if_fail=True
    )
    
    # 3. 检查优化结果并调仓
    if optimized_weights is None or optimized_weights.empty:
        log.warn("组合风险平价优化失败,维持原仓位或平均配置")
        return
    
    log.info("风险平价优化各标的权重结果:\n", optimized_weights)
    
    total_value = context.portfolio.total_value
    for stock, weight in optimized_weights.items():
        target_val = total_value * weight
        order_target_value(stock, target_val)

3. 风险平价策略的核心注意事项

  1. 数据与复权:资产配置回测强烈建议在 initialize 中通过 set_option('use_real_price', True) 开启真实价格模式,以避免未来复权因子带来的未来函数偏移。
  2. 计算传入日期:优化器中的 date 参数应传入 context.previous_date(前一交易日),切勿传入当天的未收盘时间,防止引入未关闭Bar的未来行情。
  3. 求解失败处理:由于约束条件过严或数据缺失可能导致优化失败(返回 None),策略中需对结果做类型检查,加入兜底保护逻辑(如保持现仓或转为等权重配置)。