RSI 取得 (python)
RSIの取得が上手くいったっぽいので忘れないうちに自分用に説明を書きます、
よければ参考にしてください。
RSIの種類
①単純移動平均を使って求めるもの(カトラー作)
②α=1/期間の指数移動平均(指数平滑移動平均、指数加重移動平均)を使って求めるもの(j.w.ワイルダー作)
③指数移動平均を使って求めるもの(α=2/(n+1))
(③についてはネットにほとんど書いてなかったので稀だと思いますが一応そういう算出方法をあるようなので注意)
自分は「指数移動平均って直近の値だけ2倍するやり方」ってイメージが強かったので
「クソ!何度やり直してもRSIの数値がおかしくなっちまう」って感じでした。
正しくは②です(というよりtradingviewなどは②)
具体的な計算式については記事の下に参考サイトを貼ってあるのでそちらで確認してください。
過去データを使った1時間足のRSIを算出するコード
(※ コードの乗せ方がいまだにわからないので画像ですみません。)
1枚目の画像の部分のコードはhttps://ryota-trade.com/ さんの記事中のものを一部使わせてもらってます。
なので2、3枚目の画像の部分を説明していきます。
・まず3枚目のメイン処理について
upper = 値上がり幅
lower = 値下がり幅
を入れるリストを作ります。
差分の計算は一番古いデータからはできないので
i = 0ではなく1にしています
now_range = price[i]["close_price"]-price[i-1]["close_price"
]で今の足と前回の足の値幅を計算しています。
if 前回より値が上がっているとき
elif 前回より下がっているとき
else 前回とまったく一緒のとき
と処理にしています
(一応確認したらまったく同じときも稀にあるようなのでこうしました。)
具体的にいうと、
ifのとき 値上がり幅のリストに値上がり分を追加して、値下がり幅のリストにはマイナスではなく0を追加します。
最後の if文でiがRSI算出期間の2倍以上のときにRSIを求める処理をします。
(なんで2倍なのかあとで説明)
・ 2枚目のRSIを求める関数について
RSIの平均値上がり幅、値下がり幅は指数移動平均で求めるので、
今回の平均値上がり幅を求めるのに前回の平均値上がり幅が必要になり
前回の平均値上がり幅を求めようとすると前々回の平均値上がり幅が必要になる
前々回の平均値上がり幅を求めるためには当然前々々回の平均値上がり幅が・・・
なのでRSIの期間が6だとしたら
11足前までさかのぼって
11~6足前までの6足でまず単純移動平均を出し、
6足前のときの平均値上がり幅を
(現在の値上がり幅+上で出したSMA)÷期間(6)
で5足前の平均値上がり幅を求められます。
for i in range(value-1):
期間6なのでここではiに0~4までの数字を繰り返し入れていきます。
(※range(n)は0からnの1つ前までの数字 という意味なので注意)
このループで4足前、3足前、2足前、1足前、と繰り返されていき、
現在足の平均値上がり幅が求められます
(値下がり幅の方もまったく同じやり方です)
最後にRSIの公式
平均値上がり幅÷(平均値上がり幅+平均値下がり幅)×100
かなり分かりづらくてすみません
リストからのスライスが[-1]で一番新しいやつになるのでかなりややこしくて頭が爆発しそうになりました。いまいちわかんなかったら自分で考えてみて下さい。
検証
実際に合ってるか確かめます。
・今回のコードで出したRSI
(一番下の数値は現在足のもの)
・TradingView
4つ前の46は一致しています
正直この画像じゃ全然検証できませんでした;;
計算自体は合ってると思います(強引)
ただ、TVにより近い数値にしたい場合はRSIをどんどん引き継いで求めるやり方がいいです。
以上です、いろいろ意見ください。
参考にさせてもらったサイト
https://fxcashback.info/rsi-calculation/
https://ryota-trade.com/?p=5175