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

聚宽 ETF 超卖共振两日游策略:RSI、CCI、布林带与放量收阳多指标共振实现指南

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

问题描述

JoinQuant ETF 超卖共振策略:如何组合 RSI、CCI 与布林带信号?
如何在聚宽中实现多个超卖指标至少满足两个、同时满足布林带下轨和放量收阳条件的 ETF 两日游策略?

解决方案

策略核心逻辑设计

本策略是一个典型的短线超卖反弹(两日游)策略,适用于波动率较大、具有均值回归特性的 ETF 标的。为了提高信号的可靠性,策略引入了多指标共振机制

  1. 超卖指标共振(3选2)
    • RSI (6日) < 25(极度超卖)
    • CCI (14日) < -150(超跌区间)
    • WR (10日威廉指标) > 85(处于底部区域)
    • 条件:上述三个超卖信号中,至少有两个同时满足。
  2. 价格与通道位置
    • 收盘价跌破布林带下轨(BOLL Down, 20日,2倍标准差),表明价格偏离均值过大,存在强烈的均值回归需求。
  3. 量价确认(放量收阳)
    • 当日收阳线(收盘价 > 开盘价)。
    • 当日成交量大于 5 日均量(放量)。
  4. 出场机制(两日游)
    • 持有满 2 个交易日后,在第三个交易日开盘时无条件市价卖出平仓。

聚宽(JoinQuant)策略源码实现

以下是基于聚宽 API 实现的完整策略代码。策略开启了真实价格(动态复权)模式,并使用 attribute_history 获取历史数据进行指标计算。

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

def initialize(context):
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    
    # 过滤掉比error级别低的log
    log.set_level('order', 'error')
    
    # 设定交易税费:ETF买入免印花税,佣金万分之三
    set_order_cost(OrderCost(close_tax=0.0, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='fund')
    
    # 策略参数设置
    g.etf_pool = [
        '510300.XSHG', # 沪深300ETF
        '510500.XSHG', # 中证500ETF
        '159915.XSHE', # 创业板ETF
        '518880.XSHG', # 黄金ETF
        '513100.XSHG'  # 纳指ETF
    ]
    
    # 记录持仓天数
    g.hold_days = {} # key: security, value: days_held
    
    # 每天 09:30 运行
    run_daily(market_open, time='09:30')

def market_open(context):
    # 1. 出场逻辑:持有满2天,第3天开盘卖出
    for security in list(context.portfolio.positions.keys()):
        if security in g.hold_days:
            g.hold_days[security] += 1
            if g.hold_days[security] >= 2: # 持有满2个交易日
                order_target(security, 0)
                log.info(f"持有满2天,卖出平仓: {security}")
                del g.hold_days[security]

    # 2. 进场逻辑
    # 过滤出当前未持仓的候选ETF
    available_cash = context.portfolio.available_cash
    if available_cash <= 0:
        return
        
    buy_list = []
    for security in g.etf_pool:
        if security in context.portfolio.positions:
            continue
            
        # 获取计算指标所需的数据
        # 布林带需要20日,CCI需要14日,为了计算稳定获取40天数据
        hist = attribute_history(security, 40, '1d', ['open', 'close', 'high', 'low', 'volume'])
        if len(hist) < 40:
            continue
            
        closes = hist['close'].values
        highs = hist['high'].values
        lows = hist['low'].values
        opens = hist['open'].values
        volumes = hist['volume'].values
        
        # 计算技术指标
        # RSI (6)
        rsi = talib.RSI(closes, timeperiod=6)[-1]
        # CCI (14)
        cci = talib.CCI(highs, lows, closes, timeperiod=14)[-1]
        # WR (10)
        wr = talib.WILLR(highs, lows, closes, timeperiod=10)[-1] # TALIB的WR范围是 -100 到 0
        wr_val = abs(wr) # 转换为 0 到 100
        
        # 布林带下轨 (20, 2)
        upper, middle, lower = talib.BBANDS(closes, timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)
        boll_down = lower[-1]
        
        # 5日均量
        ma_vol5 = volumes[-5:].mean()
        
        # 信号判断
        # 1. 超卖指标3选2
        oversold_signals = 0
        if rsi < 25: oversold_signals += 1
        if cci < -150: oversold_signals += 1
        if wr_val > 85: oversold_signals += 1
        
        cond_oversold = (oversold_signals >= 2)
        
        # 2. 价格跌破布林带下轨
        cond_boll = (closes[-1] < boll_down)
        
        # 3. 放量收阳
        cond_volume_price = (closes[-1] > opens[-1]) and (volumes[-1] > ma_vol5)
        
        # 共振触发
        if cond_oversold and cond_boll and cond_volume_price:
            buy_list.append(security)
            
    # 执行买入(资金均分给触发信号的ETF)
    if buy_list:
        cash_per_share = available_cash / len(buy_list)
        for security in buy_list:
            order_value(security, cash_per_share)
            g.hold_days[security] = 0
            log.info(f"触发超卖共振,买入入场: {security}")

关键API与技术细节解析

  1. set_option('use_real_price', True)
    强烈建议在 ETF 交易中开启真实价格模式。由于 ETF 存在分红折算,真实价格模式能确保回测时撮合价格与历史真实盘口一致,避免前复权带来的未来函数干扰。
  2. attribute_historyTALIB
    策略使用聚宽内置的 TALIB 库计算 RSICCIWILLRBBANDS。注意,TALIB.WILLR 计算出的威廉指标区间为 [-100, 0],因此代码中使用了 abs(wr) 将其转换为常规的 [0, 100] 进行判断。
  3. 出场计数器 g.hold_days
    使用全局字典记录每个标的的持仓天数。在每日开盘时,先对已持仓标的进行计数累加,达到 2 天则执行 order_target(security, 0) 卖出,实现精准的“两日游”短线控制。