相対力指数(Relative Strength Index)

 

概要
図1 RSI(14)の表示例

RSIは、J・ウェイルズ・ワイルダー氏が1978年に開発したオシレーター系の指標で日本では相対力指数とも呼ばれます。一定期間内の値上がり幅と値下がり幅の合計から全体の値動きに占める値上がりと値下がりの幅の比率を求め、値上がりと値下がりのどちらの勢いが強いかを示す指標です。またワイルダーのRSIの指数移動平均を単純移動平均に置き換えた物をカトラーのRSIとよびます。このサイトではカトラーのRSIについて説明しています。

図1のようにレートと同時に表示し、RSIが一定範囲(30%-70%)より外の数値を取り続ける場合は30%以下なら売られ過ぎ、70%以上なら買われ過ぎと相場が過熱していることを示します。相場が過熱感を示している場合は、次にトレンド転換が起きる可能性を示唆しています。

n区間におけるRSIの計算方法(5日間で計算する場合)

RSIの計算は一定期間内の値上がり幅と全体の値動きの幅(値上がり幅と値下がり幅の和)の比率を取ることで変動率を計算します。ここでは5日分のデータを用意し例として計算してみます。計算式は

$$ \begin{eqnarray} \rm{\sum^5(値上がり幅)}&=&\rm{(1日目の値上がり幅+2日目の値上がり幅+3日目の値上がり幅} \\ &+&\rm{4日目の値上がり幅+5日目の値上がり幅)} \\ \rm{\sum^5(値下がり幅)}&=&\rm{(1日目の値下がり幅+2日目の値下がり幅+3日目の値下がり幅} \\ &+&\rm{4日目の値下がり幅+5日目の値下がり幅)} \\ \rm{RSI(5)}&=&\rm{\sum^5(値上がり幅)/\{\sum^5(値上がり幅)+\sum^5(値下がり幅)\} \times 100(\%)} \end{eqnarray} $$

となり、結果は次の表の通りになります。

日数     価格   値上がり幅の合計   値下がり幅の合計   RSI(%) 
1日目1.0000
2日目5.004.000100.00
3日目9.004.00+4.000100.00
4日目3.004.00+4.006.0057.14
5日目7.004.00+4.00+4.006.0066.67
6日目10.004.00+4.00+4.00+3.006.0071.43
7日目2.004.00+4.00+3.006.00+8.0044.00
8日目8.004.00+3.00+6.006.00+8.0048.15
9日目4.004.00+3.00+6.008.00+4.0052.00
10日目(最新)6.00  3.00+6.00+2.008.00+4.0047.83

RSIは0~100%の値を値を取ります。50%を中心として50%より上が上昇局面、50%より下が下降局面となります。また、一般的に70%以上で「買われ過ぎ」、30%以下で「売られ過ぎ」となり相場に過熱感があると判断します。

RSIは区間nに対して一般には次にように書くことができます。

$$ \rm{RSI(n)}=\rm{\sum^𝑛(値上がり幅)/\{\sum^𝑛(値上がり幅)+\sum^𝑛(値下がり幅)\} \times 100(\%)}  \\ $$

nとして良く使われる値は以下の通りです。これらは慣例的によく使われる値ですが、目的によって調整するとよいかもしれません。


日足でnとしてよく使われる数

   9日、14日、22日、30日、42日、52日

週足でnとして良く使われる数

   9週、13週

Pythonによる実装

必要なライブラリを読み込みます

!pip install mpl_finance #Collaboratoryに入っていないライブラリを読み込みます
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd
import mpl_finance
import sys
import numpy as np
from datetime import datetime
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
import requests
import io

データをcsvファイルから読み込みます

#ファイルの読み込み
URL = "https://neulab.co.jp/wp-content/uploads/pseudo_data.csv" #csvファイルのURL

datafile = requests.get(URL)#ファイルの読み込み

#データフレームの作成
df_temp = pd.read_csv(io.BytesIO(datafile.content), header=0, index_col=0, parse_dates=True, encoding="UTF-8")

df = df_temp.loc[:,['Open','High','Low','Close']]
df.head()

RSIを計算します

df_close = df['Close']
df_diff = df_close.diff()

df_up = df_diff.copy()
df_down = df_diff.copy()

df_up[df_up < 0] = 0
df_down[df_down > 0] = 0

df_up_sum = df_up.rolling(14).sum()
df_down_sum = df_down.abs().rolling(14).sum()

df_RSI = df_up_sum/(df_up_sum + df_down_sum) * 100

matplotを使ったチャートの表示と保存例です

canvas_color = '#fffafa'
line_color = '#c8ced1'
font_color = '#171510'
colorup = '#bf0000'
colordown = '#006fbf'

n_data = -100
data = df[n_data:]
ohlc = np.vstack((range(len(data)), data.T)).T

fig, (ax1, ax2) = plt.subplots(2, 1, gridspec_kw={'height_ratios': [10, 6]}, sharex=True, figsize=(12,9))
fig.patch.set_facecolor(canvas_color)
ax1.patch.set_facecolor(canvas_color)
mpl_finance.candlestick_ohlc(ax1, ohlc, width=0.5, alpha=1, colorup=colorup, colordown=colordown)
ax2.patch.set_facecolor(canvas_color)
ax2.plot(range(len(data)), df_RSI.values[n_data:], color='red', ls='-', label='RSI')
ax1.grid()
ax2.grid()


#ロゴ読み込み
logoURL = "https://neulab.co.jp/wp-content/uploads/logo.png" #ロゴファイルのURL
img_c = plt.imread(logoURL)
imagebox = OffsetImage(img_c, zoom=0.020) #画像をimageboxにいれる。
imagebox.image.axes = ax1
im_sabo = AnnotationBbox(imagebox, (0, 9850), xybox=(0, 9900), xycoords="data", boxcoords="data", pad=0.3, frameon=False)

l1,l2 = ax2.get_legend_handles_labels()
ax2.legend(l1,l2, fontsize=14, edgecolor='none', facecolor=canvas_color)

ax1.add_artist(im_sabo)
ax1.set_ylabel("Price of Something", fontsize=22)
ax1.set_xlim(-5, 105.)
ax1.set_ylim(9000., 10000.)
ax1.yaxis.tick_right()
ax1.yaxis.set_label_coords(0, 0.5)
ax1.tick_params(labelsize=24, labelcolor=font_color, color=line_color)

ax1.spines['left'].set_linewidth(0)
ax1.spines['right'].set_linewidth(0)
ax1.spines['top'].set_linewidth(0)
ax1.spines['bottom'].set_linewidth(0)

ax2.yaxis.tick_right()
ax2.set_ylim([0, 100])
ax2.tick_params(labelsize=22, labelcolor=font_color, color=line_color)
#ax2.set_yticks(np.linspace(0,100,6))

ax2.spines['left'].set_color(line_color)
ax2.spines['right'].set_color(line_color)
ax2.spines['top'].set_color(line_color)
ax2.spines['bottom'].set_color(line_color)

xtick0 = 2
plt.xticks(range(xtick0,len(data),12), [x.strftime('%m/%d') for x in df.index][xtick0::12])

plt.subplots_adjust(left=0.05, right=0.89, bottom=0.1, top=0.99)
plt.grid(which='major',color=line_color,linestyle='-')
plt.grid(which='minor',color=line_color,linestyle='-')

ax2.grid(linestyle='--', lw=1)
ax1.set_axisbelow(True)

#上下のバンド描画
bandx = [-5,-5,105,105]
banddown = [30,0,0,30]
bandup = [70,100,100,70]
ax2.fill(bandx,bandup,color="b",alpha=0.1)
ax2.fill(bandx,banddown,color="b",alpha=0.1)

fig.savefig('RSI.png', facecolor=fig.get_facecolor(), edgecolor='none')

以上のコードをGoogle社の提供しているColaboratory上で公開しており、実際に動作させることができます。

リンクはこちら

予想
図2 RSI(14)の使い方

図2を見てください。nを14としたRSI(14)を実際のレートにあてはめたものです。RSIが70%より上では買われ過ぎと考えて、70%以上から下に戻るタイミングで逆張りを行い売りでのエントリーを考え、30%より下では売られ過ぎと考えて、こちらも上に戻るタイミングで逆張りでの買いエントリーを考えることができます。ただし、トレンドが続くような場合はRSIが70%以上や30%以下に張り付いてしまうような例がみられるので注意が必要です。

注意点

RSIは買いと売りの勢いがどうなのかを判断する指標です。買われ過ぎ、売られ過ぎといった過熱感を売買の方向性の目安にすることはできますが、タイミングを計ることはできないので、他の指標とうまく組み合わせて、売買が反転するタイミングを捉える必要があります。

また、 RSIはレンジ相場の場合に有効に機能すると言われています。 対して、トレンドが強く買いや売りが続くような場合は、RSIが100%近辺にあるいは0%近辺に張り付いてしまい、有効に機能しないことがあります。


※このHPページで紹介しているテクニカル指標を使った取引ルールや売買シグナルの見方は一般的な考え方に基づくものであり、利益の増加や損失の減少を保証するものではありません。ご自身の判断にてお取引いただきますようお願いいたします。


現在、ニューラボでは人工知能による取引アルゴリズムを開発中です。11月にリリース予定。乞うご期待!
自動取引にご興味を持たれましたら お問い合わせページよりお気軽にお問合せください。