ゆるFX ~RSI を Pine と Python で実装~
前回に続き、pineスクリプト学習中です。
今日は、RSI (Relative Strength Index) をやります。
RSIとは
また目安として、RSIの数値が70%以上になると買われ過ぎゾーン、逆に30%以下になると売られ過ぎゾーンに入るとされています。
PineでRSI実装
さっそくPineスクリプトを書いていきます。
今回のバージョン違いの注意点です。
バージョン4では、合計の関数は sum だったところ、
バージョン5からは、 math.sma とmathを付ける必要があります。
RSIの計算式は以下です。
A:X日間の値上がり幅の平均
B:X日間の値下がり幅の平均
書籍や他サイト等で、RSIを使ったサンプルコードがあると思いますが、利用する際は計算式が間違っていないかは注意してチェックするといいと思います。
# @version=5
indicator(title = "Relative Strength Index", shorttitle = "RSI", precision = 1)
# 入力部分を作成する
Source = input.source(title = "ソース", defval = close)
RSI_Length = input.int(title = "RSIの本数", defval = 12, minval = 2, maxval = 20)
isDisplayRSI_Signal = input.bool(title = "RSIシグナルを表示する", defval = true)
RSI_Signal_Length = input.int(title = "RSIシグナルの本数", defval = 12, minval = 2, maxval = 20)
# 関数を定義する
Wilder_RSI(source, length) =>
delta = source - source[1]
plus = math.sum(delta > 0 ? delta : 0, length)
minus = math.sum(delta < 0 ? delta : 0, length)
plus / (plus - minus) * 100
# 関数を使用し計算する
RSI = Wilder_RSI(Source, RSI_Length)
RSI_Signal = ta.sma(RSI, RSI_Signal_Length)
# プロットする
plot(RSI, title = "RSI", style = plot.style_line, color = color.black, linewidth = 2)
plot(RSI_Signal, title = "RSIシグナル", style = plot.style_line, color = color.new(color.gray, isDisplayRSI_Signal ? 0 : 100), linewidth = 1, editable = false)
PythonでRSI実装
今回はPythonでもRSIの算出をしてみました。
データの読み込みから前処理もやるので、pineスクリプトよりは少し長くなりましたが、計算部分は大差ないです。
import pandas as pd
import datetime as dt
import tpqoa
from pylab import mpl, plt
plt.style.use('seaborn')
mpl.rcParams['savefig.dpi'] = 300
mpl.rcParams['font.family'] = 'serif'
#%%
oanda = tpqoa.tpqoa('pyalgo.cfg')
ins = oanda.get_instruments()
instrument = 'EUR_USD'
start = dt.datetime(2022, 4, 4)
stop = dt.datetime(2022, 4, 5)
#%%
granularity = 'M10'
price = 'M'
df = oanda.get_history(instrument, start, stop, granularity, price)
df.info()
print(df[['c', 'volume']].head())
#%%
close = df['c']
diff = close.diff()
close[0:10]
#%%
diff[0:10]
#%%
diff = diff[1:]
#%%
up, down = diff.copy(), diff.copy()
up[up < 0] = 0
down[down > 0] = 0
#%%
up_sma_14 = up.rolling(window=14, center=False).mean()
down_sma_14 = down.abs().rolling(window=14, center=False).mean()
#%%
RS = up_sma_14 / down_sma_14
RSI = 100.0 - (100.0 / (1.0 + RS))
#%%
fig, (ax1, ax2) = plt.subplots(2,1, gridspec_kw = {'height_ratios':[3, 1]})
ax1.plot(close.index, close)
ax2.plot(RSI.index, RSI);
#%%
RSI.dropna(how='any')
次回も引き続き何か実装ネタを書こうと思います
いつもありがとうございます! いただいたサポートは開発費(サーバー運用費)などに使わせていただきます!