3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 JoinQuant(聚宽)平台中,通过 portfolio_optimizer(投资组合优化器)可以根据目标函数和约束条件自动求解最优资产权重。如果您希望将组合的风险控制在特定范围内,可以使用 AnnualStdConstraint(组合年化收益率标准差限制) 来约束组合的年化波动率。
AnnualStdConstraint 用于设定组合年化收益率标准差(即年化波动率)的上限。
AnnualStdConstraint(limit, count=250)
limit (float):组合年化收益率标准差(波动率)的上限,例如 0.15 表示年化波动率不超过 15%。count (int, 可选):计算收益率和波动率所向前参考的历史交易日天数,默认为 250(约 1 个交易年)。下面的示例展示了如何在月度调仓策略中使用 portfolio_optimizer,并加入 AnnualStdConstraint 限制组合年化波动率不超过 15%。
# 导入 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)
# 按月定时运行调仓
run_monthly(market_open, monthday=1, time='09:30', reference_security='000300.XSHG')
def market_open(context):
# 设定候选股票池(以沪深300部分成分股为例)
securities = get_index_stocks('000300.XSHG')[:20]
# 优化目标:组合收益最大化
target = MaxProfit(count=250)
# 约束条件:
# 1. 组合总权重在 90% 到 100% 之间
# 2. 限制组合年化波动率(标准差)不超过 15%
constraints = [
WeightConstraint(low=0.9, high=1.0),
AnnualStdConstraint(limit=0.15, count=250)
]
# 单标的权重边界:每只股票权重在 0% 到 10% 之间
bounds = [Bound(low=0.0, high=0.1)]
# 运行投资组合优化器
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:
print("优化计算成功,目标权重如下:")
print(optimized_weight)
total_value = context.portfolio.total_value
# 卖出不在优化结果中的持仓
for stock in context.portfolio.positions:
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("警告:组合优化求解失败,请检查约束条件是否过于苛刻。")
AnnualStdConstraint(limit=...) 过于严格(例如小于股票池中所有资产的最低波动率组合),优化器可能无法求解并返回 None。建议设置合理的阈值(如 0.15 - 0.25)或将 return_none_if_fail 设置为 False。WeightConstraint(总权重限制)或 Bound(单标的持仓上限)共同使用,以防资金过于集中在少数低波动股票上。count):默认参考过去 250 个交易日。如果股票上市时间较短,计算协方差矩阵或波动率可能受影响。