3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在量化投资中,某些因子的数值越小往往代表标的的潜在表现越好(例如低估值因子 PE/PB、低波动率因子或风险指标)。在 JoinQuant(聚宽) 平台上,为了给这类“打分越小越优”的标的赋予更高权重,我们可以使用投资组合优化器(portfolio_optimizer)中的 MinScore 目标函数。
MinScore 是 JoinQuant 投资组合优化模块提供的一种优化目标:
在聚宽策略中,使用 MinScore 需要引入优化器库:
from jqlib.optimizer import portfolio_optimizer, MinScore, Bound, WeightConstraint
target = MinScore(scores)
scores (pandas.Series): 必填参数,Index 为股票代码(如 '000001.XSHE'),Value 为对应的数值或打分。以下示例展示了如何在聚宽平台利用 MinScore 目标函数,对选定股票池根据反向指标(如低 PE 因子)进行组合权重优化:
import pandas as pd
from jqdata import *
from jqlib.optimizer import portfolio_optimizer, MinScore, Bound, WeightConstraint
def initialize(context):
# 设定基准与交易参数
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(rebalance, monthday=1, time='09:30', reference_security='000300.XSHG')
def rebalance(context):
# 1. 获取沪深300成分股作为选股池
stocks = get_index_stocks('000300.XSHG')[:30] # 示例取前30只
# 2. 查询财务数据(如市盈率 PE)作为打分依据
q = query(valuation.code, valuation.pe_ratio).filter(valuation.code.in_(stocks))
df_pe = get_fundamentals(q, date=context.previous_date)
if df_pe.empty:
return
# 构建打分 Series(PE越低,Score越小)
scores = pd.Series(df_pe['pe_ratio'].values, index=df_pe['code'].values).dropna()
valid_stocks = list(scores.index)
# 3. 使用 MinScore 进行组合优化
# 目标:打分(PE)越低权重越高;约束:组合总权重在90%-100%,单股持仓不超过15%
optimized_weight = portfolio_optimizer(
date=context.previous_date,
securities=valid_stocks,
target=MinScore(scores=scores),
constraints=[WeightConstraint(low=0.9, high=1.0)],
bounds=[Bound(low=0.0, high=0.15)],
return_none_if_fail=True
)
# 4. 执行调仓
if optimized_weight is not None:
log.info("优化权重成功:", optimized_weight)
# 卖出不在优化结果中的持仓
for stock in context.portfolio.positions.keys():
if stock not in optimized_weight or optimized_weight[stock] == 0:
order_target_value(stock, 0)
# 按优化比例下单
total_value = context.portfolio.total_value
for stock, weight in optimized_weight.items():
order_target_value(stock, total_value * weight)
else:
log.warn("组合优化失败,保持现有持仓")
MinScore 的 scores 中不能包含 NaN 或 Inf,需提前过滤或填充缺失值。MinScore 可能会将大部分权重集中在打分最低的一两只股票上,因此必须配合 bounds=[Bound(low, high)] 限制单标的最高持仓比例,并设置行业或市场暴露约束,以分散风险。MaxScore;若是“越小越好”(如 PE、PB、波动率),请选用 MinScore。