🚀 AI 一键生成 joinquant 策略代码

JoinQuant RSI 指标策略 Python 实现详解:如何识别超买超卖?

joinquant | 发布时间: 2025/11/26
以下内容由 EasyQuant 生成。

问题描述

如何编写一个基于 RSI 指标的超买超卖策略?

解决方案

编写一个基于 RSI(相对强弱指标)的超买超卖策略,核心逻辑通常如下:

  1. 计算 RSI 指标:通常使用过去 14 个交易日的收盘价计算。
  2. 超卖买入(Oversold):当 RSI 数值低于设定下限(通常为 30 或 20),认为市场处于超卖状态,价格可能反弹,执行买入
  3. 超买卖出(Overbought):当 RSI 数值高于设定上限(通常为 70 或 80),认为市场处于超买状态,价格可能回调,执行卖出

以下是基于聚宽(JoinQuant)API 实现的完整策略代码。

RSI 超买超卖策略代码

# -*- coding: utf-8 -*-
import jqdata
import talib
import numpy as np

def initialize(context):
    """
    初始化函数,设定基准、手续费、滑点及策略参数
    """
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    
    # 设置股票交易手续费(万三佣金,千一印花税)
    set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5), type='stock')
    
    # --- 策略参数设置 ---
    # 要操作的标的(这里以平安银行为例)
    g.security = '000001.XSHE'
    # RSI 时间周期
    g.rsi_period = 14
    # 超买阈值(卖出信号)
    g.rsi_high = 70
    # 超卖阈值(买入信号)
    g.rsi_low = 30
    
    # 每天开盘时运行策略
    run_daily(market_open, time='every_bar')

def market_open(context):
    """
    每日交易逻辑
    """
    security = g.security
    
    # 1. 获取历史收盘价数据
    # 获取长度需要比 RSI 周期长,以确保计算结果稳定,这里取 100 天
    # skip_paused=True 跳过停牌数据
    h_data = attribute_history(security, 100, '1d', ['close'], skip_paused=True)
    
    # 如果数据不足(例如新股),则跳过
    if len(h_data) < g.rsi_period + 1:
        return
        
    # 将收盘价转换为 numpy 数组,供 talib 使用
    close_prices = h_data['close'].values
    
    # 2. 计算 RSI 指标
    # 使用 talib 库计算 RSI,返回的是一个数组
    rsi_values = talib.RSI(close_prices, timeperiod=g.rsi_period)
    
    # 获取最新的 RSI 值(数组的最后一个元素)
    current_rsi = rsi_values[-1]
    
    # 获取当前持仓数量
    curr_position = context.portfolio.positions[security].total_amount
    # 获取当前可用资金
    available_cash = context.portfolio.available_cash
    
    # 3. 交易逻辑判断
    
    # 信号:RSI < 30 (超卖),且当前无持仓 -> 买入
    if current_rsi < g.rsi_low and curr_position == 0:
        log.info("RSI超卖 (值: %.2f),触发买入: %s" % (current_rsi, security))
        # 全仓买入
        order_value(security, available_cash)
        
    # 信号:RSI > 70 (超买),且有持仓 -> 卖出
    elif current_rsi > g.rsi_high and curr_position > 0:
        log.info("RSI超买 (值: %.2f),触发卖出: %s" % (current_rsi, security))
        # 清空仓位
        order_target(security, 0)
        
    # 记录 RSI 值到图表,方便回测查看
    record(RSI=current_rsi)

代码关键点解析

  1. 数据获取 (attribute_history):
    • 我们需要获取历史收盘价来计算 RSI。
    • 虽然 RSI 周期是 14,但为了计算的平滑和准确性(TALib 内部算法需要前序数据),我们获取了过去 100 天的数据。
  2. 指标计算 (talib.RSI):
    • 聚宽环境内置了 talib 库,这是计算技术指标最高效的方法。
    • 输入必须是 numpy.array 格式的收盘价序列。
  3. 交易逻辑:
    • 买入条件: current_rsi < 30。这意味着市场情绪过度悲观,可能即将反弹。
    • 卖出条件: current_rsi > 70。这意味着市场情绪过度乐观,可能即将回调。
  4. 仓位控制:
    • 示例中使用 order_value 进行全仓买入,使用 order_target(security, 0) 进行清仓卖出。

常见问题 Q&A

Q: 为什么 attribute_history 获取的数据长度要比 RSI 周期长?
A: RSI 的计算(特别是 Wilder 平滑算法)具有“记忆性”,数据序列越长,计算出的当前 RSI 值越精确。如果只获取 15 天数据计算 14 日 RSI,结果可能与看盘软件有较大偏差。

Q: 如何将此策略修改为多只股票轮动?
A: 可以将 g.security 修改为一个股票列表(如 get_index_stocks('000300.XSHG')),然后在 market_open 函数中使用 for 循环遍历每只股票,分别计算 RSI 并独立判断买卖。

Q: RSI 阈值可以调整吗?
A: 可以。在牛市中,RSI 经常在高位钝化,可以将超买阈值调高至 80;在熊市中,可以将超卖阈值调低至 20。也可以结合其他指标(如 MACD 或均线)来过滤假信号。

Q: 为什么使用 talib 而不是自己写公式计算?
A: talib 是底层用 C 语言编写的金融库,计算速度极快且经过了广泛验证,比自己用 Python 编写循环或 Pandas 计算效率更高且更不容易出错。