3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于聚宽(JoinQuant)平台的投资组合优化策略,旨在通过 jqlib.optimizer 库中的 最大化夏普比率(MaxSharpeRatio) 模型来分配仓位。
MaxSharpeRatio 模型,寻找在给定风险下收益最高的组合权重。Bound(0, 0.1)),防止持仓过于集中。weight_sum_equal=1.0)。# -*- coding: utf-8 -*-
from jqdata import *
from jqlib.optimizer import *
import pandas as pd
def initialize(context):
"""
初始化函数
"""
# 设定基准为沪深300
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 过滤掉order系列API产生的比error级别低的log
log.set_level('order', 'error')
# 设定手续费:买入万三,卖出万三加千一印花税,最低5元
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
# 设定每月第一个交易日进行调仓
run_monthly(rebalance, monthday=1, time='09:30')
def rebalance(context):
"""
调仓主函数
"""
log.info("开始进行组合优化调仓...")
# 1. 获取股票池:沪深300
stock_pool = get_index_stocks('000300.XSHG')
# 2. 过滤停牌和ST股票
current_data = get_current_data()
stock_pool = [stock for stock in stock_pool
if not current_data[stock].paused
and not current_data[stock].is_st]
# 如果股票池为空,则不操作
if len(stock_pool) == 0:
return
# 3. 组合优化配置
# 目标:最大化夏普比率
# rf=0.0: 无风险利率设为0
# weight_sum_equal=1.0: 权重之和为1
# count=250: 使用过去250个交易日的数据计算协方差矩阵和预期收益
target = MaxSharpeRatio(rf=0.0, weight_sum_equal=1.0, count=250)
# 边界约束:每只股票权重范围 0% ~ 10%
# 这样可以避免资金过度集中在某一只股票上
bounds = [Bound(0.0, 0.1)]
# 调用优化器
# 注意:优化器计算需要一定时间,且可能因为数据不足或无法收敛而返回None
optimized_weight = portfolio_optimizer(
date=context.previous_date,
securities=stock_pool,
target=target,
bounds=bounds,
ftol=1e-09, # 精度控制
return_none_if_fail=True
)
# 4. 执行交易
if optimized_weight is None:
log.warn("组合优化失败,本次不调仓")
return
# 获取当前账户总资产
total_value = context.portfolio.total_value
# 先卖出:不在优化结果中的,或者权重降低的
# 获取当前持仓
current_positions = context.portfolio.positions
for stock in current_positions.keys():
if stock not in optimized_weight.index:
order_target_value(stock, 0)
# 买入/调整:按照优化后的权重下单
# 遍历优化结果
for stock, weight in optimized_weight.items():
# 计算目标持仓市值
target_value = total_value * weight
# 下单调整到目标市值
order_target_value(stock, target_value)
log.info("调仓完成")
portfolio_optimizer 函数:
date=context.previous_date:使用前一交易日的数据进行计算,避免未来函数。return_none_if_fail=True:如果优化求解失败(例如数据不足或无解),返回 None,策略中做了相应的判断处理,防止报错停止。MaxSharpeRatio 目标:
count=250 表示使用过去一年的数据来估算波动率和收益率,这是比较常用的参数。Bound 约束:
Bound(0.0, 0.1),优化器可能会将 100% 的资金分配给历史上表现最好的一两只股票,导致风险过度集中。限制单只股票权重是工程实践中必要的风控手段。交易执行:
order_target_value 可以直接根据目标市值下单,系统会自动计算需要买入或卖出的股数,非常方便。Q: 为什么选择沪深300作为股票池?
A: 沪深300指数包含了A股市场中规模大、流动性好的300只股票。对于组合优化算法(特别是涉及协方差矩阵计算的算法),数据的完整性和股票的流动性非常重要。如果使用小盘股,可能会因为停牌、流动性不足或数据缺失导致优化器求解失败。
Q: 策略中的 count=250 可以修改吗?
A: 可以。count 代表用于计算历史统计量(如均值、方差)的回溯天数。
Q: 为什么优化器有时会返回 None?
A: 常见原因包括:
Q: 如何进一步改进这个策略?
A:
BarraConstraint 来控制行业暴露或风格暴露(如限制在某个行业的权重不超过20%)。