Python 株価の価格帯別出来高をグラフ化する

'23/11/14更新:チャートと価格帯別出来高のグラフサイズの割合を変更したコードに変えました。
 本記事では、下図のようなグラフを作成する雛形コードを載せました。下図左にはチャート図、右には価格帯別出来高図を表記します。

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

f:id:HK29:20220305222329p:plain

そして、下図は本プログラムの処理によって得た最終的なデータです。

f:id:HK29:20220305222427p:plain

 

■本プログラム

import pandas as pd
import numpy as np
from dateutil import relativedelta
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import japanize_matplotlib
plt.rcParams['font.size'] = 22 # グラフの基本フォントサイズの設定
import datetime
now = datetime.datetime.now()

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

# 日付型へ変換
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

df2 = df.copy()

df2['Ave'] = (df['Open'] + df['High'] + df['Low'] + df['Close']) / 4
df2

# 現在から3年前のデータまでを対象にするため、時間の演算
# 秒, 時間, 日の場合
#my_time = now + datetime.timedelta(days = 3, hours = 5)
# 月, 年の場合は、dateutilのrelativedeltaを使う
my_time = now + relativedelta.relativedelta(years = -10)
print(my_time.year, my_time.month, my_time.day)

DF = df2.copy()
# #DF = DF[DF['Time'] > datetime.datetime(2019, 1, 1)]
DF = DF[DF['Time'] >  datetime.datetime(my_time.year, my_time.month, my_time.day)]
DF.reset_index(drop = True, inplace = True)
DF

# インデックスを列名で指定
DF.set_index('Time', inplace=True)
DF

# 価格帯の最小と最大を算出
min = int(DF['Ave'].min())
max = int(DF['Ave'].max())

# 階級の境界を算出
my_classes = 21
my_bins = np.arange(min, max, int((max-min)/my_classes))

# 階級に分けて、カテゴリ列を作成する
DF['Category'] = pd.cut(DF['Ave'], my_bins)

#価格別出来高の計算
my_sum = DF.groupby('Category').sum()
label_list = [str(i) for i in my_sum.index]

# 単純移動平均の計算
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()

### データの可視化
fig = plt.figure(figsize=(21,9))

# 株価チャートのグラフを描く
ax1 = fig.add_axes([0.1, 0.1, 0.5, 0.8])  # [左端, 下端, 幅, 高さ]
ax1.plot(DF['Close'], color="k", lw=3)
ax1.set_ylabel('株価 [円]')
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.legend()

# X軸目盛表記を調整する
x_ticklabels = ax1.get_xticklabels() # デフォルトの目盛り表記をゲットする
plt.setp(x_ticklabels, rotation=75) # 目盛り表記を90度回転。#フォントサイズの指定する場合 ,fontsize=16)
tick_spacing = 180 # 目盛り表示する間隔(3か月=90日)
ax1.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing)) # X軸目盛の表示間隔を間引く
ax1.grid()
ax1.set_title(fiel_path)

# 価格帯別の出来高のグラフを描く
ax2 = fig.add_axes([0.72, 0.1, 0.15, 0.8])
ax2.barh(label_list, my_sum['Volume'], color="g")
ax2.set_xlabel('出来高')
ax2.set_ylabel('価格帯')

#plt.show()
plt.savefig(f'{fiel_path[:-4]}.jpg', bbox_inches='tight')

以上

<広告>