Python 实现股票指标计算——RSI

RSI (Relative Strength Index) - 相对强弱指标

1 公式

1.1 第一种计算公式

假设A为N日(N一般取值为6、14、21)内收盘价的正数之和

B为N日内(N一般取值为6、14、21)收盘价的负数之和乘以(-1)

这样,A和B均为正,将A、B代入RSI计算公式,则

RSI(N) = \frac{A}{A+B}\times 100
1.2 第二种计算公式

RS(相对强度)= N日内收盘价涨数和之均值÷N日内收盘价跌数和之均值
RSI(相对强弱指标)= 100-\frac{100}{1+RS}

2 数据准备

我们以科创50指数 000688 为例,指数开始日期为2019-12-31,数据格式如下:

3 计算过程

3.1 公式1
def calculate_rsi(df: pd.DataFrame, window: int = 14) -> pd.DataFrame:
    """
    计算给定DataFrame中股票的相对强弱指数(Relative Strength Index, RSI)。

    参数
    ----------
    df : pd.DataFrame
        包含股票价格信息的DataFrame,必须包含'date'和'close'两列。
    window : int, optional
        用于计算RSI的周期窗口长度,默认为14天。

    返回值
    -------
    data : pd.DataFrame
        原始DataFrame,附加了名为'rsi'的新列,该列包含了计算出的RSI值。

    """

    # 创建DataFrame的副本,避免修改原始数据
    data = df.copy()
    
    # 确保'date'列是datetime类型,这对于时间序列分析很重要
    data['date'] = pd.to_datetime(data['date'])

    # 计算每日收盘价的变化量
    delta = data['close'].diff()

    # 将变化量分为正收益(gain)和负收益(loss),非正收益设为0,非负收益取相反数
    gain = delta.where(delta > 0, 0)
    loss = -delta.where(delta < 0, 0)

    # 使用滚动窗口计算过去N天的累计收益和累计损失
    gain_sum = gain.rolling(window).sum()
    loss_sum = loss.rolling(window).sum()

    # 计算RSI
    rsi = gain_sum / (gain_sum + loss_sum) * 100

    # 将计算出的RSI值添加到DataFrame中
    data['rsi'] = rsi

    # 返回带有RSI值的DataFrame
    return data
3.2 公式2
def calculate_rsi(df: pd.DataFrame, window: int = 14) -> pd.DataFrame:
    """
    计算给定DataFrame中股票的相对强弱指数(Relative Strength Index, RSI)。

    参数
    ----------
    df : pd.DataFrame
        包含股票价格信息的DataFrame,必须包含'date'和'close'两列。
    window : int, optional
        用于计算RSI的周期窗口长度,默认为14天。

    返回值
    -------
    data : pd.DataFrame
        原始DataFrame,附加了名为'rsi'的新列,该列包含了计算出的RSI值。

    """

    data = df.copy()
    
    # 确保'date'列是datetime类型
    data['date'] = pd.to_datetime(data['date'])

    # 计算每日收盘价变化
    delta = data['close'].diff()

    # 将变化量分为正收益(gain)和负收益(loss)
    gain = delta.clip(lower=0)
    loss = (-delta).clip(lower=0)

    # 计算平均收益和平均损失的EMA
    avg_gain = gain.ewm(com=window-1, min_periods=window).mean()
    avg_loss = loss.ewm(com=window-1, min_periods=window).mean()

    # 避免分母为零的情况,如果avg_loss为零,则设RS为极大值
    rs = avg_gain / avg_loss
    rs = rs.fillna(0)  # 将NaN替换为0
    rs[rs == float('inf')] = 1000000  # 将无穷大替换为极大值

    # 计算RSI
    rsi = 100 - (100 / (1 + rs))

    # 当avg_loss为零时,确保RSI为100
    rsi[avg_loss == 0] = 100

    # 将计算出的RSI值添加到DataFrame中
    data['rsi'] = rsi

    return data

4 注意事项

公式2计算的结果与股票软件上显示的结果一致

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值