3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在聚宽(joinquant)平台中,通过投资组合优化器模块 jqlib.optimizer,管理者可以在满足多种约束条件(如年化收益率下限、仓位占比限制、单标的权重上限等)的前提下,实现特定目标的最大化。对于因子选股,MaxFactorValue 目标函数可以帮助我们在限定风险和约束的同时,尽可能赋予因子得分较高的标的更高的权重。
portfolio_optimizerportfolio_optimizer 是聚宽提供的核心优化函数,主要参数如下:
date: 优化执行的日期(一般传入 context.previous_date 避免未来函数)。securities: 拟进行权重分配的股票/标的列表。target: 优化目标,此处选用 MaxFactorValue(factor, count)。constraints: 约束条件列表,例如收益率约束 AnnualProfitConstraint 或市场约束等。bounds: 单标的权重限制,如 Bound(0, 0.2) 表示单只股票权重不超过 20%。MaxFactorValuefactor: 自定义的 Factor 类或聚宽因子库中的因子。count: 过去计算因子的天数窗口(默认为 1)。000300.XSHG)、开启动态复权 set_option('use_real_price', True) 及交易手续费。jqfactor.Factor 类。例如定义 5 日均值人气指标(AR)因子。portfolio_optimizer,传入 MaxFactorValue 目标以及所需的约束条件与边界。order_target_value 进行批量调整。import pandas as pd
from jqdata import *
from jqfactor import Factor
from jqlib.optimizer import *
# 1. 定义因子:人气指标5日均值
class AR_M5(Factor):
name = 'ar_m5'
max_window = 5
dependencies = ['AR']
def calc(self, data):
return data['AR'].mean()
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成分股作为候选股票池
g.buy_list = get_index_stocks('000016.XSHG')
def market_open(context):
# 卖出不在候选池中的股票
sell_list = set(context.portfolio.positions.keys()) - set(g.buy_list)
for stock in sell_list:
order_target_value(stock, 0)
# 调用投资组合优化器
# 目标:'人气指标5日均值'最大化
# 约束:组合年化收益率目标下限为 10%
# 边界:单只标的权重介于 0 到 20% 之间
optimized_weight = portfolio_optimizer(
date=context.previous_date,
securities=g.buy_list,
target=MaxFactorValue(factor=AR_M5, count=1),
constraints=[AnnualProfitConstraint(limit=0.1, count=250)],
bounds=[Bound(0.0, 0.2)],
default_port_weight_range=[0.0, 1.0],
ftol=1e-09,
return_none_if_fail=True
)
# 检查优化结果并调仓
if optimized_weight is None:
log.warn('警告:组合优化失败,保持当前持仓')
else:
log.info('组合优化成功,目标权重如下:')
print(optimized_weight)
total_value = context.portfolio.total_value
for stock, weight in optimized_weight.items():
target_value = total_value * weight
order_target_value(stock, target_value)
date 参数应为 context.previous_date,切勿使用当天的价格或实时财务数据进行组合优化。None。设置 return_none_if_fail=True 可以有效防止策略异常中断,并可在代码中做好降级处理(如维持现状或退化为等权重配置)。ftol 参数(如 1e-08 或 1e-09)可以平衡优化计算的精度和响应执行速度。