PythonでRSI=相対力指数を計算してみた(Pythonでテクニカル指標シリーズ)
こんばんは、新米データサイエンティスト(@algon_fx)です。昨日は勉強をした後に、久しぶりに家で晩酌をしたのですが、安い焼酎のおかげで、今朝は目覚めが悪かったです。やっぱりお酒は良いものと悪いもので影響が違うものですね。(デジャブや)
昨日はOANDA API v20を一足先に使ってみました。今日もAPIと戯れようかと計画していたのですが、少しまとまった時間を作ってやりたいので一旦お預けにします。
今日はPythonでテクニカル指標シリーズとして、RSI(相対力指数 – Relative Strength Index)の勉強をしていきます。
【人気記事】
RSI(相対力指数)とは?
なんと、このテクニカル指標も開発されたのは1978年と非常に年季の入った指標です。RSIはオシレーター系のテクニカル指標で、「逆張り」の取引手法となります。
Relative Strength Indexの略で、全体の為替レートの変動幅に対して、どれくらい上昇したかを判断する指標となっています。
最大の特徴として「レンジ相場」のみしか使うことができません。為替レートが一定の幅で下がったり上がったりを繰り返している相場の時に、「上りすぎてるから下がる」「下がりすぎたから上がる」を判断するわけです。
RSIの計算方法
では具体的にRSIの計算方法を紐解いていきましょう。EMAと比べるととっても単純で簡単です。(EMAに恨みがあるわけではないですが笑)
RSI = 期間中の値上がり幅 ÷ (期間中の値上がり幅 + 値下がり幅)x 100%これでRSIの計算は完了です。非常に簡単ですね(笑)なお、RSIを開発した方はこの期間を14日間と推奨しています。
計算方法を見ると理解できますが、RSIは為替レートの「値動きの幅」を利用しています。この値動きの幅を指標として計算することで、現在の為替相場が「買われ過ぎなのか」「売られ過ぎなのか」を判断するわけですね。
また、移動平均線などは為替レートそのものを計算して指標化しているのに対して、RSIはレートの値動きの幅を計算していることで「今のレートの勢い」が測れるわけですね。
全くもって頭の良い指標ですね。ちなみに、RSIの計算方法ですが、上昇幅と下落幅を「指数平滑移動平均(EMA)」で算出する方法もあります。
RSIの使い方
前述した通りRSIの指標で判断できるのは「買われ過ぎ」「売られ過ぎ」です。またRSI単体で使われることはなく、移動平均線なのトレンド系指標と合わせ使われます。
RSIの計算方法を見ても分かる通りパーセンテージ(割合)で表現される指標です。もっとも一般的なRSIの使い方は下記の通りです。
・RSIが70〜80%以上=売りサイン(買われ過ぎてる!)
・RSIが20〜30%以下=買いサイン(売られ過ぎてる!)
めっちゃシンプルな使い方ですね。実際に下のチャートで確認してみましょう。こちらですが、上段がドル円の1分ローソク足、下段が期間14のRSIです。
RSIのチャート上にピンク色で囲まれていますが、この部分が 30%〜70% を表しています。(つまりこのピンク色の部分を超えたらサイン発生)
まずはRSIの青丸に注目してみましょう。こちらですが、RSIの値が30%を下回っているのがわかります。ここが買いサインです。実際にその後の相場は上昇へ転換していますね。
ただし、RSIで注意しなくてはいけないのがトレンド相場の時です。次は赤丸をみてください。こちらも青丸同様にRSIが30%を下回っている=つまり買いサインが出ているわけですが、レートを見てみると、確かに一瞬戻しそうな雰囲気はありましたが、そのまま下降トレンドへ入っています。
(少し例題が判りづらいですが)このようにRSIは「レンジ相場」でしか、シグナルの効果が現れません。そのため、RSIを利用する際は、移動平均線などのトレンド系指標でトレンドを読みながら使う必要があるわけです。
RSIをPythonを使って書いてみる
さて、いよいよ本題のRSI(相対力指数)をPythonで実際に計算をしてみましょう。計算式は簡単で理解しやすいですが、実際にPythonで書くと少しめんどかったです。
使ったバージョンとライブラリ
- Python 3.6
- Jupyter
- Pandas
- Numpy
- Matplotlib(グラフ描写だけ)
まずはライブラリをインポートしましょう。
1 2 3 4 5 6 7 8 |
#ライブラリ import pandas as pd import time import matplotlib.pyplot as plt import datetime %matplotlib qt |
次に使う為替のデータセットを読み込みましょう。今回は毎度おなじみの USD_JPY_Week2.csv を使いました。こちらのファイルの準備の仕方は「過去の為替レートデータ」の記事をご参照ください。
1 2 3 4 5 6 7 8 9 10 11 12 |
# 過去のドル円レートのCSVを読み込んで簡単な前処理 df = pd.read_csv('USD_JPY_Week2.csv', index_col='DateTime', names=['Tid', 'Dealable', 'Pair', 'DateTime', 'Buy', 'Sell'], skiprows=1) df.index = pd.to_datetime(df.index) del df['Tid'] del df['Dealable'] del df['Pair'] min_1 = df.resample('1Min', how='ohlc') buy_1min = min_1.xs('Buy', axis=1, drop_level=True) buy_1min_l = buy_1min[0:200] buy_1min_l = buy_1min_l.fillna(method='ffill') |
上の前処理のコードをみて頂ければ判りますが、1分足にして、さらに1週間分のデータを200分に切り分けてます。加えて、欠損値が結構あるので、f illna(method=’ffill’) で欠損値の穴埋めをしています。
念のためデータを確認しておきましょう。
1 2 3 4 |
# 最初の5行を表示 buy_1min_l.head() |
かなり雑(特に欠損の処理)ですが、とりあえずドル円の1分足のデータが出来ました。次は本題のRSIを処理してあげましょう。
まずはbuy_1min_lの終値(close)を抜き出して、 diff() を使って差分を計算します。
1 2 3 4 5 |
# データセットから終値のみ切り出して差分を計算 close = buy_1min_l['close'] diff = close.diff() |
これで問題ないと思いますが、念のため確認しておきましょう。これが間違っていると、RSIの計算がごちゃごちゃになってしまうので。
1 2 3 4 5 6 7 |
# 終値の最初の10行 close[0:10] # 差分の最初の10行 diff[0:10] |
左が close で右が差分を処理した diff です。元データの1行目2行目をみると106.634と106.641で差分が0.007計算できます。差分(上図の右側)の最初のレコードをみると0.007となっているので、計算に間違いはなさそうですね。(当たり前)
差分を処理した diff ですが、最初の1行目がNaNになってしまうので、こちらを落としてあげましょう。
1 2 3 4 |
# 最初のレコードが欠損してしまうので落としてあげる diff = diff[1:] |
では、次は値上がり幅と値下がり幅の処理を行いましょう。上で処理した差分の diff を up と down としてPandasシリーズへ切り分けて、それぞれ値上がり時以外(または逆の値下がり時以外)は0としてあげます。
1 2 3 4 5 6 |
# 値上がり幅、値下がり幅をシリーズへ切り分け up, down = diff.copy(), diff.copy() up[up < 0] = 0 down[down > 0] = 0 |
これで、RSIを算出するのに必要な前処理は完了です。他のテクニカル指標は為替レートそのものの処理が多かったですが、RSIは値動きの幅という特殊な指標なので、前処理が少し手間ですね。
では、RSIを計算すべく、値上がり幅( up )と値下がり幅( down )の単純移動平均(14)をそれぞれ計算してあげましょう。(参照:移動平均のPythonの書き方はこちら)
1 2 3 4 5 |
# 値上がり幅/値下がり幅の単純移動平均(14)を処理 up_sma_14 = up.rolling(window=14, center=False).mean() down_sma_14 = down.abs().rolling(window=14, center=False).mean() |
では、次はいよいよRSIの計算です。RSI(Relative Strength Index)はパーセンテージで表される指標です。まずはRS(Relative Strength)を計算してあげて、そのあとIndexにしてあげましょう。
1 2 3 4 5 |
# RSIの計算 RS = up_sma_14 / down_sma_14 RSI = 100.0 - (100.0 / (1.0 + RS)) |
最後に確認をしてみましょう。Matplotlibを使って、元の1分足ドル円終値と今回処理したRSIのプロッティングしてみよう。
1 2 3 4 5 6 7 8 9 |
#RSIをMatplotlibでプロッティング fig, (ax1, ax2) = plt.subplots(2,1, gridspec_kw = {'height_ratios':[3, 1]}) ax1.plot(close.index, close) ax2.plot(RSI.index, RSI) fig.tight_layout() plt.show() |
良い感じですね!下のチャートがRSIですが、18:41付近で買いのサインが出ています。上の終値のグラフを見てみると、下降から上昇へ転じているのがわかりますね。
まとめと次への課題
今日はPythonを使ってRSI(相対力指数)を計算してみました。計算式や使い方などを勉強してみて、非常にユニークかつ発想として面白いテクニカル指標ですね。
ただ、手法としては「逆張り」なので…実際に機械学習FXでモデルへ組み込む際は要注意かもしれないです。(早くテクニカル指標を全てやり終えてモデル構築ゴリゴリしたい)
以上です!ブログ読んでいただきありがとうございます!Twitterでも色々と発信しているので、是非フォローお願いします!
ディスカッション
コメント一覧
まだ、コメントがありません