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

joinquant 组合优化风控:利用 RatioConstraint 限制组合 VaR 与 Sharpe 比率

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

问题描述

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

Title: joinquant 组合优化风控:利用 RatioConstraint 限制组合 VaR 与 Sharpe

Question: 在 joinquant 优化器中如何通过 RatioConstraint 限制组合的在险价值(VaR)或夏普比率?

解决方案

在 JoinQuant 中使用 RatioConstraint 限制组合 VaR 与 Sharpe

在 JoinQuant(聚宽)的投资组合优化器 portfolio_optimizer 中,RatioConstraint 约束函数专门用于对组合的特定风险或收益比率进行限制(例如夏普比率、信息比率、VaR、CVaR 等)。


1. RatioConstraint 函数语法

RatioConstraint(ratio, low=None, high=None, rf=None, benchmark=None, count=250)

参数说明:

  • ratio (str): 比率类型,支持 "sharpe_ratio""var""cvar""information_ratio""calmar_ratio""omega_ratio""sortino_ratio" 等。
  • low (float): 比率下限,若不限制则为 None
  • high (float): 比率上限,若不限制则为 None
  • rf (float): 无风险利率,适用于 sharpe_ratioomega_ratio,默认为 0。
  • benchmark (str): 参照基准,适用于 information_ratio,默认为 '000300.XSHG'
  • count (int): 回溯计算收益率的历史天数,默认为 250 天。

2. 核心场景代码示例

限制在险价值(VaR)

假设要求组合每日风险在特定置信度下的在险价值(VaR)不低于 -3%(即最大单日预期的风险损失不超过 3%):

from jqlib.optimizer import RatioConstraint

# 设置在险价值下限为 -0.03
var_constraint = RatioConstraint(ratio='var', low=-0.03, count=250)

限制夏普比率(Sharpe Ratio)

假设要求组合的预期夏普比率不低于 1.0(年化无风险利率设为 2%):

from jqlib.optimizer import RatioConstraint

# 设置夏普比率下限为 1.0
sharpe_constraint = RatioConstraint(ratio='sharpe_ratio', low=1.0, rf=0.02, count=250)

3. 完整策略应用示例

下面展示如何在聚宽策略中调用 portfolio_optimizer 并配合 RatioConstraint 进行投资组合权重优化:

import pandas as pd
from jqdata import *
from jqlib.optimizer import portfolio_optimizer, MaxProfit, RatioConstraint, Bound

def initialize(context):
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)
    run_monthly(rebalance, monthday=1, time='09:30')

def rebalance(context):
    # 选定标的池(以沪深300前10只股票为例)
    securities = get_index_stocks('000300.XSHG')[:10]
    
    # 定义目标函数:追求组合收益最大化
    target = MaxProfit(count=250)
    
    # 定义限制条件:通过 RatioConstraint 限制 VaR 不低于 -3%
    constraints = [
        RatioConstraint(ratio='var', low=-0.03, count=250)
    ]
    
    # 个股权重限制:单只股票权重 0% ~ 20%
    bounds = [Bound(low=0.0, high=0.2)]
    
    # 求解最优权重
    optimized_weight = portfolio_optimizer(
        date=context.previous_date,
        securities=securities,
        target=target,
        constraints=constraints,
        bounds=bounds,
        ftol=1e-09,
        return_none_if_fail=True
    )
    
    if optimized_weight is not None:
        # 按照求解出的权重进行调仓
        total_value = context.portfolio.total_value
        for stock, weight in optimized_weight.items():
            order_target_value(stock, total_value * weight)
    else:
        log.warn("组合优化失败,维持原有持仓")