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

joinquant 组合优化器:如何设置年化收益率预期限制(AnnualProfitConstraint)?

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

问题描述

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

Title: joinquant 组合优化器:如何设置年化收益率预期限制(AnnualProfitConstraint)?

Question: 请问在 joinquant 组合优化中,如何限制组合的预期年化收益率?

解决方案

joinquant 组合优化器:设置年化收益率预期限制(AnnualProfitConstraint)指南

在 JoinQuant(聚宽)量化平台上,利用投资组合优化器 portfolio_optimizer 构建策略时,如果需要对组合的预期收益进行约束,可以使用 AnnualProfitConstraint 限制函数。


1. AnnualProfitConstraint 简介

AnnualProfitConstraint 是一个限制函数(Constraint),用于设定组合优化结果的年化收益率预期下限。优化器在计算组合标的权重分配时,会确保最终构建的组合在历史回溯计算中的预期年化收益率不低于设定的阈值。

API 语法

AnnualProfitConstraint(limit, count=250)
  • limit (float): 预期年化收益率的下限阈值。例如 0.1 表示年化收益率目标下限为 10%,0.2 表示 20%。
  • count (int): 向前获取收益率(returns)计算的历史天数,默认值为 250(约一个交易年)。

2. 代码示例

以下示例展示了如何在聚宽策略中结合 portfolio_optimizer 使用 AnnualProfitConstraint,实现“组合风险最小化(最小化组合方差),且年化收益率下限为 10%”的优化模型:

import pandas as pd
from jqdata import *
from jqlib.optimizer import *

def initialize(context):
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)
    
    # 设置调仓运行计划
    run_monthly(market_open, monthday=1, time='9:30', reference_security='000300.XSHG')

def market_open(context):
    # 1. 设定股票池(以沪深300成分股前15只为例)
    buy_list = get_index_stocks('000300.XSHG')[:15]
    
    # 2. 优化器目标函数:组合风险最小化
    target = MinVariance(count=250)
    
    # 3. 设置约束条件:
    # - 组合总权重限制在 90% 到 100% 之间
    # - 组合预期年化收益率下限设为 10% (0.1)
    constraints = [
        WeightConstraint(low=0.9, high=1.0),
        AnnualProfitConstraint(limit=0.1, count=250)
    ]
    
    # 4. 执行投资组合优化
    optimized_weight = portfolio_optimizer(
        date=context.previous_date,
        securities=buy_list,
        target=target,
        constraints=constraints,
        bounds=[Bound(0.0, 0.2)],  # 每只标的权重不超过 20%
        default_port_weight_range=[0.0, 1.0],
        ftol=1e-09,
        return_none_if_fail=True
    )
    
    # 5. 根据优化结果进行调仓
    if optimized_weight is not None:
        total_value = context.portfolio.total_value
        # 卖出不在优化结果中的持仓
        for stock in context.portfolio.positions.keys():
            if stock not in optimized_weight or optimized_weight[stock] == 0:
                order_target_value(stock, 0)
        # 调仓至目标权重
        for stock, weight in optimized_weight.items():
            order_target_value(stock, total_value * weight)
    else:
        print('警告:组合优化求解失败,保持现有持仓或执行备用逻辑')

3. 注意事项

  1. 求解失败处理:如果设置的收益率目标过度激进(如 limit=1.0 对应 100% 年化),在现有的标的池与其它约束(如标的权重上限、风险最小化等)下可能无法找到可行解。此时优化器可能返回 None(当 return_none_if_fail=True 时),策略中应包含对 None 的异常处理逻辑。
  2. 配合目标函数使用AnnualProfitConstraint 通常与 MinVariance(最小化方差)或 MinTrackingError(最小化追踪误差)等风险控制类目标函数结合使用,以在控制风险的同时确保收益底线。
  3. 历史窗口设置count 参数决定了评估历史收益率的时间跨度,建议与优化目标的 count 保持一致,以提高优化结果的稳定性。