RCI(Rank Correlation Index)

 

概要

通常の指標は、変動率や変動幅を見ますが、RCIは一定期間中の日付(時間)と価格に順位をつけて分析します。両者の相関関係をを調べ、相場の過熱感やトレンドを見ようとするオシレータ系のテクニカル指標です。

一定期間(期間n)の相場の値動きを考えて、最新を1とした時系列順と最高終値を1とした価格順にデータをそれぞれ並べて、順位を付けます。両方の順位の差を取って、相関関係を見ていきます。RCIは-100%から100%の間を推移します。図1が表示例で一般に、+80%から+100%は高値圏、-80%から-100%は安値圏と言われています。また、RCIを実際に使う場合は、単体で使用したり、2本3本と計算期間を変えたRCIを組み合わせて使います。

図1 RCIの表示例
計算方法(日足の場合)

RCIは日付順位と価格順位から計算します。例えば、3日間のデータがあり日付順が(1, 2, 3)、価格順が(2, 3, 1)のような場合、日付順位と価格順位の差を期間n(ここではnは3)日分取り2乗した値dを計算します。

$$ \rm{} d = (1-2)^2 + (2-3)^2 + (3-1)^2 = (1 + 1 + 4) = 5 $$

次にRCIを次の計算式で計算します。

$$ \rm{} RCI = \{1 – \frac{6d}{n(n^2 -1 )}\} \times 100 (\%)\\ = {1 – \frac{30}{3(3^2 -1)}} \times 100 = 25.00 $$

RCIは25.00%と計算されます。

さらに具体例を使って計算してみましょう。簡単のために5日間上げ続ける場合と5日間下げ続ける場合を考えてみます。この場合はn=5となります。

日数 終値  日付順位価格順位順位差の二乗    d    RCI    
1日目50055$$(5-5)^2 = 0$$
2日目51044$$(4-4)^2 = 0$$
3日目51533$$(3-3)^2 = 0$$
4日目52022$$(2-2)^2 = 0$$
5日目(最新)53011$$(1-1)^2 = 0$$0      100

単調に上げていく場合はdが0となるのでRCIは100%となります。次に単調に下げていく場合を考えます。

日数 終値  日付順位価格順位順位差の二乗    d    RCI    
1日目53051$$(5-1)^2 = 16$$
2日目52042$$(4-2)^2 = 4$$
3日目51533$$(3-3)^2 = 0$$
4日目51024$$(2-4)^2 = 4$$
5日目(最新)50015$$(1-5)^2 = 16$$40      -100

dが40となり、RCIは$$1-240/120 \times 100$$から-100%となります。2つの例からRCIが-100%から100%の間を推移することも理解できます。

よく使われるnの値としては、

などがあげられます。短期と中長期に分けているのは、短期線と長期線の2本を使用する場合など複数のRCIを組み合わせて使う場合に対応しています。

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

疑似データを読み込みます

#ファイルの読み込み
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()

RCIを計算します

df['tp'] = df.loc[:,['High', 'Low', 'Close']].mean(axis='columns')

#5日分のシフトデータを用意
df['tp2'] = df['tp'].shift(1)
df['tp3'] = df['tp'].shift(2)
df['tp4'] = df['tp'].shift(3)
df['tp5'] = df['tp'].shift(4)
df['RCI'] = 0
 
for idx in range(df.shape[0]):
    value = df.iloc[ [idx], 4:9].rank(axis=1, ascending=False) #大きさ順のインデックスを取得
    value = value.fillna(0.0)
    d = 0
    for i in range(5):
        d = d + (i+1 - value.iat[0,i])**2
        
    df.iat[idx, 9] = (1 - 6*d/(5*(5**2 -1 ))) * 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['RCI'].values[n_data:], color='red', ls='-', label='RCI')
ax1.grid()
ax2.grid()

#ロゴ読み込み
logoURL = "https://neulab.co.jp/wp-content/uploads/logo.png" #logoファイルの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, 9950), 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_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([-105,105])
ax2.tick_params(labelsize=22, labelcolor=font_color, color=line_color)

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 = [20,0,0,20]
bandup =[80,100,100,80]
ax2.fill(bandx,bandup,color="b",alpha=0.1)
ax2.fill(bandx,banddown,color="b",alpha=0.1)

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

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

リンク先はこちら

予想

1本のRCIで見る場合は次のように判断することができます。

図2が1本のRCIで予想を立てたときの代表的な売り買いのポイントです。(値動きからわかる代表的な点のみですべてを表示していません。)

図2 RCIの予想例(単独、代表例)

複数のRCIを使う場合の例です。短期(n=9)、長期(n=13)の2本のRCIラインを使います。 この場合は以下のような売買ポイントが追加できます。

ただし、頻繁に交差は起きるのでダマシが多くなります。

注意点

RCIの計算期間を長くするほど、価格の動きを捉えづらくなります。また強いトレンドが続くと100%や-100%には張り付くことが多くなります。


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


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