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

聚宽红利增强策略:如何用排名缓冲降低换手并保留赢家?

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

问题描述

聚宽红利增强策略:如何用排名缓冲降低换手并保留赢家?
如何在聚宽红利增强策略中加入买入严格、卖出宽松的排名缓冲机制,同时保留原有盈利持仓并只对新股票增量调仓?

解决方案

在量化多因子选股策略(如红利增强策略)中,高换手率往往会因为印花税和佣金(滑点)吞噬掉大部分超额收益。为了解决这一痛点,我们可以引入排名缓冲机制(Rank Buffer)。其核心逻辑是:买入时要求极高(必须进入前N名),卖出时要求宽松(跌出M名才卖,M > N)。同时,在调仓时,我们优先保留已在持仓中的赢家,仅对新纳入的股票进行增量资金配置。

以下是在聚宽(JoinQuant)平台实现该机制的完整方案与 Python 策略源码。

一、 核心设计逻辑

  1. 红利因子构建:使用聚宽因子库或财务数据(如股息率 dividend_payable / market_capbook_to_price_ratio)对股票池进行打分排名。
  2. 买入缓冲区(严格):只有红利排名进入前 $N$(例如前10名)的股票,才具备买入资格。
  3. 卖出缓冲区(宽松):已持仓的股票,只要其红利排名没有跌出 $M$(例如前20名,且 $M > N$),就继续持有,不进行卖出。只有跌出前 $M$ 名时才强制平仓。
  4. 增量调仓
    • 卖出跌出缓冲区的股票,释放现金。
    • 计算当前保留持仓的价值,剩余可用资金均分给新买入的、排名进入前 $N$ 的股票。

二、 聚宽策略源码实现

请在聚宽回测环境中运行以下代码(按天回测,建议开启真实价格模式 set_option('use_real_price', True)):

import pandas as pd
import numpy as np
from jqdata import *

def initialize(context):
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    
    # 股票类交易手续费:买入万三,卖出万三加千一印花税,最低5元
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
    # 策略参数设置
    g.N = 10  # 严格买入线:前10名
    g.M = 20  # 宽松卖出线:前20名(缓冲区间为 11-20 名)
    
    # 定时运行:每月第一个交易日开盘调仓
    run_monthly(my_rebalance, monthday=1, time='09:30')

def get_dividend_rank(context):
    # 获取沪深300成分股
    stocks = get_index_stocks('000300.XSHG')
    
    # 查询财务数据:获取最新一季度的账面价值与市值比(作为红利/价值增强因子)
    # 也可以使用聚宽因子库中的 book_to_price_ratio
    q = query(
        valuation.code,
        valuation.pb_ratio
    ).filter(
        valuation.code.in_(stocks)
    )
    df = get_fundamentals(q)
    
    # 账面市值比 = 1 / 市净率 (PB)
    df['bp_ratio'] = 1.0 / df['pb_ratio']
    df = df.dropna().sort_values(by='bp_ratio', ascending=False) # 降序排列,值越大红利属性越强
    
    # 返回股票代码的排名列表
    return list(df['code'])

def my_rebalance(context):
    # 1. 获取最新的红利因子排名
    ranked_stocks = get_dividend_rank(context)
    if not ranked_stocks:
        return
        
    # 2. 获取当前持仓列表
    current_positions = list(context.portfolio.positions.keys())
    
    # 3. 确定卖出决策(宽松:跌出前 M 名的卖出)
    to_sell = []
    keep_holding = []
    for stock in current_positions:
        if stock in ranked_stocks:
            rank = ranked_stocks.index(stock) + 1  # 索引从0开始,排名从1开始
            if rank > g.M:
                to_sell.append(stock)
            else:
                keep_holding.append(stock)  # 保留赢家持仓
        else:
            to_sell.append(stock)  # 不在成分股内的强制卖出
            
    # 执行卖出操作
    for stock in to_sell:
        order_target(stock, 0)
        log.info("股票 %s 跌出前 %d 名(卖出线),执行平仓" % (stock, g.M))
        
    # 4. 确定买入决策(严格:只有前 N 名且不在当前持仓中的才买入)
    candidate_buys = ranked_stocks[:g.N]
    to_buy = [stock for stock in candidate_buys if stock not in keep_holding]
    
    # 5. 增量资金分配与调仓
    # 计算当前保留持仓的股票数量和新买入的股票数量
    total_target_count = len(keep_holding) + len(to_buy)
    if total_target_count == 0:
        return
        
    # 获取当前总资产
    total_value = context.portfolio.total_value
    # 每只股票的目标分配价值(等权重分配)
    target_value_per_stock = total_value / total_target_count
    
    # 对保留的赢家持仓进行价值微调(增量调仓,防止过度交易)
    for stock in keep_holding:
        # 只有当当前持仓价值与目标价值偏差大于20%时才调整,进一步降低换手率
        current_stock_value = context.portfolio.positions[stock].value
        if abs(current_stock_value - target_value_per_stock) / target_value_per_stock > 0.20:
            order_target_value(stock, target_value_per_stock)
            
    # 对新纳入的股票进行买入
    for stock in to_buy:
        # 确保有足够可用资金
        if context.portfolio.available_cash > target_value_per_stock * 0.8:
            order_target_value(stock, target_value_per_stock)
            log.info("新赢家股票 %s 进入前 %d 名(买入线),执行建仓" % (stock, g.N))

三、 排名缓冲机制的优势分析

  1. 显著降低换手率:如果仅使用前10名进行调仓,每次排名微调(如第10名跌到第11名)都会触发全仓换股。引入 $11 \sim 20$ 名的缓冲区后,第10名的股票只要不跌破第20名,就会被继续持有,避免了频繁的摩擦成本。
  2. 保留赢家效应:红利因子具有一定的动量效应。留在缓冲区的股票往往是刚刚释放完红利、但基本面依然优秀的“赢家”,继续持有能充分享受其超额收益。
  3. 增量调仓避免冲击:通过 order_target_value 结合偏差阈值(如代码中的 0.20 偏差限制),策略不会因为每日微小的净值波动去频繁调整已有持仓的权重,只有在新股建仓或持仓严重偏离时才交易,对实盘非常友好。