Python 株価のRSIを計算してグラフ化する

 本記事では、下図中の下段のように、テクニカル指標のひとつであるRSI(Relative Strength Index,相対力指数)を算出してグラフ化する雛形コードを載せました。

f:id:HK29:20220306234247p:plain

必要なデータは、下図のような時系列チャート情報です。例えば、次のリンク先のような手順で入手できます。Python 楽天証券のマーケットスピードⅡとエクセルRSSから、チャート時系列データをcsvで保存する「win32com」 - PythonとVBAで世の中を便利にする

f:id:HK29:20220306234144p:plain

本コードを実行すると、下図右端の列のようにRSIを計算します。そして、冒頭のようなグラフを図示します。

f:id:HK29:20220306235730p:plain

■本プログラム

#!/usr/bin/env python
# coding: utf-8

# In[1]:


import pandas as pd
import numpy as np
from dateutil import relativedelta
import datetime
now = datetime.datetime.now()

# csvファイルの読み込み
fiel_path = '8267_イオン.csv'
df = pd.read_csv(fiel_path)
df


# In[2]:


# 日付型へ変換
df['日付'] = pd.to_datetime(df['日付'])

# 不要な列を削除する
df.drop(['時刻'], axis=1, inplace=True)

# 列名を一括で変更する
target_column_list = ['日付', '始値', '高値', '安値', '終値', '出来高']
rename_column_list = ['Time', 'Open', 'High', 'Low', 'Close', 'Volume']
df.rename(columns=dict(zip(target_column_list, rename_column_list)), inplace=True)
df


# In[3]:


# 前日との差分
df_diff = df["Close"].diff(1)
df_diff


# In[4]:


# RSI計算のための上昇、下降を算出する
df_up, df_down = df_diff.copy(), df_diff.copy()
df_up[df_up < 0] = 0 # 0未満は0を代入
df_down[df_down > 0] = 0 # 0より大きいは0を代入
# 14日上昇分の平均値を計算
df_up_14 = df_up.rolling(window = 14, center = False).mean()
# 14日下降分の平均値を計算
df_down_14 = abs(df_down.rolling(window = 14, center = False).mean())
print(df_up_14)
print(df_down_14)


# In[5]:


# RSIの定義
df['RSI'] = (df_up_14 / (df_up_14 + df_down_14)) * 100
df


# In[6]:


# インデックスを列名で指定
DF = df.set_index('Time', inplace=False)
DF.to_csv(fiel_path[:-4] + '_RSI.csv')
DF # In[7]: # 単純移動平均の計算 my_days1 = 25 my_days2 = 75 my_days3 = 200 simple_moving_average1 = pd.Series.rolling(DF['Close'], window=my_days1).mean() simple_moving_average2 = pd.Series.rolling(DF['Close'], window=my_days2).mean() simple_moving_average3 = pd.Series.rolling(DF['Close'], window=my_days3).mean() # In[8]: import matplotlib.pyplot as plt import matplotlib.ticker as ticker import japanize_matplotlib plt.rcParams['font.size'] = 16 # グラフの基本フォントサイズの設定 fig = plt.figure(figsize=(10, 6)) ax1 = fig.add_subplot(2, 1, 1) ax1.plot(DF["Close"], label="Close", color='k') ax1.plot(simple_moving_average1, color="r", lw=3, label="移動平均 {} 日".format(my_days1)) ax1.plot(simple_moving_average2, color="y", lw=3, label="移動平均 {} 日".format(my_days2)) ax1.plot(simple_moving_average3, color="b", lw=3, label="移動平均 {} 日".format(my_days3)) ax1.axes.xaxis.set_visible(False) #ax1.axes.xaxis.set_ticklabels([]) ax1.grid(axis='y') ax1.set_ylabel('株価 [¥]') ax1.set_title(fiel_path) ax1.legend(bbox_to_anchor = (1.35, 0.85)) ax2 = fig.add_subplot(2, 1, 2) ax2.plot(DF["RSI"], color = 'k') ax2.axhline(y = 70, c = 'm', label = '70%') ax2.axhline(y = 50, c = 'y', label = '50%') ax2.axhline(y = 30, c = 'c', label = '30%') # X軸目盛表記を調整する x_ticklabels = ax2.get_xticklabels() # デフォルトの目盛り表記をゲットする plt.setp(x_ticklabels, rotation=45) # 目盛り表記を90度回転。#フォントサイズの指定する場合 ,fontsize=16) tick_spacing = 180 # 目盛り表示する間隔(3か月=90日) ax2.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing)) # X軸目盛の表示間隔を間引く ax2.grid() ax2.set_yticks([0, 30, 50, 70, 100]) ax2.set_ylabel('RSI [%]') ax2.legend(bbox_to_anchor = (1.0, 0.85)) plt.show() # In[ ]:

以上

<広告>