見出し画像

PythonでRSI(Relative Strength Index)を算出する

RSI(Relative Strength Index)とは

RSIは、算出期間における変動幅のうち上昇幅の占める割合を表したテクニカル指標です。

割合という表現のとおり、オシレーター系の指標です。


数式で表すと次のようになります。

RSI = 期間平均上昇幅 ÷ (期間平均上昇幅 + 期間平均下落幅) × 100


オシレーター系の指標に共通することとして、数式からも分かるように、上昇や下落が続くような状況では100や0に近い値が連続します。
どのテクニカル指標にも言えることですが、有効な状況で使うことが重要です。

投資においては、ボックス相場では有効ですがトレンド相場ではあまり有効ではありません。

売買シグナルに使う場合は、次のように判断します。
RSIが0に近いほど期間において下落し過ぎていると考えて、逆張りで買う
RSIが100に近いほど期間において上昇し過ぎていると考えて、逆張りで売る

ソースコードと実行結果

def calcRSI(**kwargs):
    """RSI(Relative Strength Index)を算出する
    
    Args:
        data (pandas.Series): 算出する対象の値
        period (int): 算出する期間
    
    Returns:
        pandas.Series: RSI
    """
    DATA = kwargs['data']
    period = kwargs['period']
    
    DATA_CHANGE = DATA - DATA.shift(1, axis=0)
    
    DATA_CHANGE_UP, DATA_CHANGE_DOWN = DATA_CHANGE.copy(), DATA_CHANGE.copy()
    
    DATA_CHANGE_UP[DATA_CHANGE_UP < 0] = 0  # 上昇以外を0にする
    DATA_CHANGE_DOWN[DATA_CHANGE_DOWN > 0] = 0  # 下落以外を0にする
    
    DATA_CHANGE_UP_MA = calcSMA(data=DATA_CHANGE_UP, period=period)
    DATA_CHANGE_DOWN_MA = calcSMA(data=DATA_CHANGE_DOWN, period=period)
    
    return DATA_CHANGE_UP_MA / (  DATA_CHANGE_UP_MA - DATA_CHANGE_DOWN_MA ) * 100

出力用のソースコードも記載しておきます。

import matplotlib.pyplot as plt
import matplotlib.dates as mdates

def plotChart(**kwargs):
    OHLCV = kwargs['ohlcv']
    start = kwargs['start']
    end = kwargs['end']
    label = kwargs['label']
    file = kwargs['file']
    
    Close = OHLCV['Close']
    RSI = calcRSI(data=Close, period=14)
    
    fig = plt.figure(figsize=(8, 6))
    ax_Price = fig.add_axes([0, 0.5, 1, 0.5])
    ax_Indicator = fig.add_axes([0, 0.0, 1, 0.5], sharex=ax_Price)
    
    ax_Price.plot(Close[start:end], color='black', marker='.')
    ax_Price.tick_params(labelright=True)
    ax_Price.grid(True)
    ax_Price.set_ylabel(label)
    
    ax_Indicator.plot(RSI[start:end], color='red')
    ax_Indicator.set_ylim([0, 100])
    ax_Indicator.tick_params(labelright=True)
    ax_Indicator.grid(True)
    ax_Indicator.set_ylabel('RSI')
    
    ax_Indicator.set_xticks(OHLCV[start:end].index)
    ax_Indicator.set_xticklabels(ax_Price.get_xticks(), rotation=90, horizontalalignment='center', fontsize='small')
    ax_Indicator.xaxis.set_major_formatter(mdates.DateFormatter('%m/%d'))
    
    fig.savefig(file, format='png', bbox_inches='tight')

次のようにplotChart関数を呼び出して実行してください。

plotChart(ohlcv=OHLCV_N225, start='20221201', end=None, label='Nikkei225', file=filename)

すると、次のようなチャートが出力されます。

ソースコードの解説

変動幅はshift関数を使用して1期間前の値との差を求めます。
元のSeriesが変更されないように上昇幅用と下落幅用のそれぞれをcopy関数で複製してから加工しています。
比較演算子で条件指定した行の抽出を活用して、上昇幅用は負の変動幅を0とみなし、下落幅用は正の変動幅を0とみなしてから単純平均を求めます。

calcSMAは以前にこちらの記事で紹介したコードを使用しています。
こちらのコードも呼び出せるようにしてください。

参考

pandas.Series.shiftのリファレンス
https://pandas.pydata.org/docs/reference/api/pandas.Series.shift.html

pandas.Series.copyのリファレンス
https://pandas.pydata.org/docs/reference/api/pandas.Series.copy.html

Indexing and selecting data - Boolean indexing
(和訳:データのインデックス作成と選択 - booleanベクトルを使用したインデックス作成)
https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#boolean-indexing


この記事が気に入ったらサポートをしてみませんか?