量化投资常用技能——指标篇3

  • 量化投资常用技能 系列文章目录
  • 前言
  • 一、RSI指标介绍
  • 二、RSI指标的数学计算过程
  • 三、RSI指标的代码实现和绘图
  • 主要的计算部分的计算方法
  • 完整的绘图代码
  • 四、RSI指标的一般研判标准
  • 单个RSI指标的基本应用
  • 长短RSI指标的一般研判标注
  • 指标缺陷



前言

由于这一部分主要是给大家介绍指标的数学公式和计算方法,更深入的了解它们,其中有众多的数学公式和理论推导过程,我尽可能排版的工整,方便各位阅读。如果只想看代码实现可以跳到最后面“代码实现”部分

RSI指标的实现其实也很容易上手,计算方式与之前的BOLL指标大同小异,核心计算部分都很容易,大家稍微阅读一下就可以很轻松的理解和使用



大家可以关注我的GitHub:ExileSaber

量化投资这部分内容会在整个包完成并调试后上传,虽然现在还没较高的水平,但是可以一起学习进步



一、RSI指标介绍

该部分主要参考百度百科的介绍

相对强弱指标,即RSI指标

投资的一般原理认为,投资者的买卖行为是各种因素综合结果的反映,行情的变化最终取决于供求关系,而RSI指标正是根据供求平衡的原理,通过测量某一个期间内股价上涨总幅度占股价变化总幅度平均值的百分比,来评估多空力量的强弱程度,进而提示具体操作。

具体的策略介绍会放在 “量化投资常用技能——决策篇” 中



二、RSI指标的数学计算过程

RSI指标简单来说就是计算N日内收盘涨幅平均值和跌幅平均值

javascript 计算 RSI指标 rsi公式代码_代码实现

通过公式我们可以发现,该指标反映出来的是N日收盘涨幅均值占N日收盘涨跌幅均值的比例。当股票价格持续上涨,向上力道较大时,计算出来的该指标值较大并呈现出上升趋势;当股票价格持续下跌,向下力道较大时,计算出来的该指标值较小并呈现出下降趋势



三、RSI指标的代码实现和绘图

分为两个部分来讲解,一个是主要的计算部分的代码,学习的同时也可以自己灵活运用在其他地方。另外就是整体的绘图部分,包括烛状图和RSI指标



主要的计算部分的计算方法

  • 涨跌幅度计算
    Series对象可以使用javascript 计算 RSI指标 rsi公式代码_数据分析_02_javascript 计算 RSI指标 rsi公式代码_数据_03函数来快速简洁的完成涨跌幅的计算,由于第一个数据无法计算涨跌幅度,所以该位置是javascript 计算 RSI指标 rsi公式代码_数据分析_04值,可以使用Series对象的javascript 计算 RSI指标 rsi公式代码_数据分析_05函数去掉javascript 计算 RSI指标 rsi公式代码_数据分析_04值,然后再转换成ndarray对象方便后续处理

代码实现如下

rate = np.array(close.pct_change().dropna())  # 计算涨跌幅度
  • RSI指标计算
    指标计算时需要判断是涨还是跌,并且还要求幅度的移动平均值,因此我们写成普通的循环方便阅读
# window是移动平均的窗口大小
for i in range(len(rate) - window + 1):
    the_rate = rate[i:i+window]  # 提取每一个窗口的数据
    up_rate = the_rate[np.where(the_rate > 0)].mean()  # 使用np.where函数判断是涨还是跌
    down_rate = the_rate[np.where(the_rate < 0)].mean()
    rsi.append(100 * up_rate / (up_rate - down_rate))




完整的绘图代码

为了绘图全面,我们将“量化投资常用技能——绘图篇 1:绘制股票收盘价格曲线和ochl烛状图”中绘制烛状图的函数 javascript 计算 RSI指标 rsi公式代码_数据_07_javascript 计算 RSI指标 rsi公式代码_python_08

缺少的库直接 pip install 安装即可

import numpy as np
import matplotlib.pyplot as plt
import pandas_datareader.data as web
import datetime
from matplotlib.dates import date2num
import mpl_finance as mpf

# ———————————————————— #
# ———— 默认参数设置 ———— #
# ———————————————————— #
__colorup__ = "red"
__colordown__ = "green"

window = 14

start = datetime.datetime(2017, 1, 1)
end = datetime.date.today()
stock = web.DataReader("600519.SS", "yahoo", start, end)  # 选择茅台股的数据

# ———————————————————— #


def plot_ochl(data_df, axs=None, show=False):
    '''
    绘制烛状图
    :param data_df: 输入的数据,输入的数据类型目前只支持DataFrame类型
    :param axs: 是否在子图上绘制
    :param show: 是否显示图像
    :return:
    '''

    if axs is None:
        fig, ax = plt.subplots(figsize=(14, 7))
        ax.spines['top'].set_visible(False)
        ax.spines['right'].set_visible(False)
        drawer = ax

    else:
        drawer = axs

    qutotes = []

    # 这部分根据实际表格情况做修改
    for index, (d, o, c, h, l) in enumerate(zip(data_df.index, data_df.Open, data_df.Close, data_df.High, data_df.Low)):
        d = date2num(d)  # 蜡烛图的日期要使用matplotlib.finance.date2num进行转换为特有的数字值
        val = (d, o, c, h, l)  # 日期,开盘,收盘,最高,最低组成tuple对象val
        qutotes.append(val)  # 加val加入qutotes

    # 使用mpf.candlestick_ochl进行蜡烛绘制,ochl代表:open,close,high,low
    mpf.candlestick_ochl(drawer, qutotes, width=0.6, colorup=__colorup__, colordown=__colordown__)
    drawer.autoscale_view()
    drawer.xaxis_date()

    if show:
        plt.show()


def rsi(stock_df, window, axs=None, show=False):
    '''
    计算RSI指标并绘图
    :param stock_df: 输入的数据,输入的数据类型目前只支持DataFrame类型
    :param window: 计算RSI的窗口大小
    :param axs: 是否在子图上绘制
    :param show: 是否显示图像
    :return:
    '''
    drawer = plt if axs is None else axs

    close = stock_df['Close']

    rate = np.array(close.pct_change().dropna())  # 计算涨跌幅度

    rsi = []

    for i in range(len(rate) - window + 1):
        the_rate = rate[i:i+window]  # 提取每一个窗口的数据
        up_rate = the_rate[np.where(the_rate > 0)].mean()  # 使用np.where函数判断是涨还是跌
        down_rate = the_rate[np.where(the_rate < 0)].mean()
        rsi.append(100 * up_rate / (up_rate - down_rate))

    drawer.plot(stock.index, 30 * np.ones(len(stock.index)), 'g--', label='30', alpha=0.6)
    drawer.plot(stock.index, 50 * np.ones(len(stock.index)), 'y-.', label='50', alpha=0.5)
    drawer.plot(stock.index, 70 * np.ones(len(stock.index)), 'g--', label='70', alpha=0.6)
    drawer.plot(stock.index[window:], rsi, label='RSI', alpha=0.8)

    drawer.legend()

    if show:
        plt.show()


fig, ax = plt.subplots(2, 1, figsize=(14, 7))
plot_ochl(data_df=stock, axs=ax[0])

rsi(stock, window, axs=ax[1], show=True)

最后的绘制效果如下:

javascript 计算 RSI指标 rsi公式代码_数据分析_09




四、RSI指标的一般研判标准

该部分主要介绍几个常见的研判标准,实际情况并不一定会和研判标准相符合

主要借鉴了百度百科的介绍,放在最后供大家学习代码后也可以了解一下一些RSI指标的研判标准

单个RSI指标的基本应用

由公式容易知道,javascript 计算 RSI指标 rsi公式代码_数据分析_10javascript 计算 RSI指标 rsi公式代码_代码实现_11

  1. 一般而言,RSI掉头向下为卖出讯号,RSI掉头向上为买入信号。但应用时宜从整体态势的判断出发
  2. RSI的M形走向是超买区常见的见顶形态;W形走向是超卖区常见的见底形态。这时,往往可见RSI走向与价格走向发生背离。所以,背离现象也是一种买卖讯号
  3. RSI由下往上走,一个波谷比一个波谷高构成上升支持线;RSI由上往下走,一个波顶比一个波顶低构成下降压力线。跌破支持线为卖出信号,升穿压力线为买入信号
  4. RSI上穿50分界线为买入信号,下破50分界线为卖出信号
  5. N日RSI的N值常见取5~14日。N值愈大趋势感愈强,但有反应滞后倾向,称为慢速线;N值愈小对变化愈敏感,但易产生飘忽不定的感觉,称为快速线。因此,可将慢速线与快速线比较观察,若两线同向上,升势较强;若两线同向下,跌势较强;若快速线上穿慢速线为买入信号;若快速线下穿慢速线为卖出信号
  6. 由于RSI设计上的原因,RSI在进入超买区或超卖区以后,即使市势有较大的波动,而RSI变动速率渐趋缓慢,波幅愈来愈微,即出现所谓钝化问题。尤其是在持续大涨或大跌时,容易发生买卖“操之过急”的遗憾。解决这个问题的办法,仅就RSI指标本身而言是调整超买区或超卖区的界定指标,如90以上、10以下;二是加大N的取值

长短RSI指标的一般研判标注

短期RSI是指参数相对小的RSI,长期RSI是指参数相对较长的RSI。比如,6日RSI和12日RSI中 ,6日RSI即为短期RSI,12日RSI即为长期RSI。长短期RSI线的交叉情况可以作为我们研判行情的方法

  1. 当短期RSI>长期RSI时,市场则属于多头市场
  2. 当短期RSI<长期RSI时,市场则属于空头市场
  3. 当短期RSI线在低位向上突破长期RSI线,则是市场的买入信号
  4. 当短期RSI线在高位向下突破长期RSI线,则是市场的卖出信号

指标缺陷

  1. RSI指标的时间参数不同,其给出的结果就会不同
    从理论上讲,较短周期的RSI指标虽然比较敏感,但快速震荡的次数较多,可靠性较差;较长周期的RSI指标尽管信号可靠,但指标的敏感性不够,反应迟缓,因而经常出现错过买卖良机的现象
    由于RSI是通过收盘价计算的,如果当天行情的波幅很大,上下影线较长时,RSI就不可能较为准确反映此时行情的变化
  2. 超买、超卖出现后导致的指标钝化现象容易发出错误的操作信号
    在"牛市"和"熊市"的中间阶段,RSI值升至90以上或降到10以下的情况时有发生,此时指标钝化后会出现模糊的误导信息,若依照该指标操作可能会出现失误,错过盈利机会或较早进入市场而被套牢
  3. RSI指标与股价的"背离"走势常常会发生滞后现象
    一方面,市场行情已经出现反转,但是该指标的"背离"信号却可能滞后出现;另一方面,在各种随机因素的影响下,有时"背离"现象出现数次后行情才真正开始反转,同时在研判指标"背离"现象时,真正反转所对应的"背离"出现次数并无定论,一次、两次或三次背离都有出现趋势变化的可能,在实际操作中较难确认
  4. 当RSI值在50附近波动时该指标往往失去参考价值
    一般而言,RSI值在40到60之间研判的作用并不大。按照RSI的应用原则,当RSI从50以下向上突破50分界线时代表股价已转强;RSI从50以上向下跌破50分界线则代表股价已转弱

在实际运用中若要 缩小这个缺点 ,可以在价格变动幅度较大且涨跌变动较频繁时,将RSI参数设定的小一点;在价格变动幅度较小且涨跌变动不频繁时,将RSI参数设定大一点