米株プログラミング[1-5](plotly 表作成編)
米株プログラミングサークルの皆様!こんにちわトミィ(@toushi_tommy)です。!今日は株価データを使って表を作ってみます。コードの詳細などは分からなくても良いです。そろそろ、図だけじゃなくて、実際の株価の詳細データを取得してデータを作っていきます。今回は作図ライブラリ plotly を使います。plotly は既にGoogleColabには標準でインストールされております。
GoogleColab立ち上げについては、省きます。分からない場合は過去のnoteをご覧ください。
日本語化
まず、今後日本語を使う為にも、以下のように日本語環境をインストールします。以下のコマンドを実行してください。
pip install japanize-matplotlib -t /content/drive/MyDrive/module
このような感じで実行します。
使い方は以下の通りですが、今回はなくても動くようです。
import japanize_matplotlib
import seaborn as sns
sns.set(font="IPAexGothic")
今後、日本語を使いますので、インストールを行っておきましょう。
ウォッチリスト表作成
今回は、ウォッチしたい銘柄の下記のデータを取ります。
「現在値」「出来高」「時価総額」「PER」「高値下落率」「年初来」「1ヶ月」「1週間」「1日」の値動きです。
まずは、下のコードをコピーして動かしてみましょう。
import sys
sys.path.append('/content/drive/MyDrive/module')
import pandas as pd
import yahoo_fin.stock_info as si
import plotly.graph_objects as go
tickers = ['VOO', 'TWTR', 'AMZN', 'OTLY', 'META', 'TSLA', 'NVDA']
header = ['Ticker','現在値', '出来高', '時価総額', 'PER','高値下落',
'年初来', '1ヶ月', '1週間', '1日']
title = "ウォッチリストデータ"
df=pd.DataFrame()
for i in range(len(tickers)):
data = si.get_data(tickers[i])
df.loc[tickers[i],'Ticker']=tickers[i]
stk_today=data["adjclose"].iat[-1]
df.loc[tickers[i],'現在値']='$%.2f'%(stk_today)
vol_today=data["volume"].iat[-1]
df.loc[tickers[i],'出来高']=vol_today
stk_max=data['adjclose'].max()
df.loc[tickers[i],'高値下落']='{:.2%}'.format((stk_today-stk_max)/stk_max)
if '2020-12-31' in data.index:
stk_yend=data.loc['2021-12-31','adjclose']
df.loc[tickers[i],'年初来']='{:.2%}'.format((stk_today-stk_yend)/stk_yend)
if len(data)>=2:
stk_yester=data['adjclose'].iat[-2]
df.loc[tickers[i],'1日']='{:.2%}'.format((stk_today-stk_yester)/stk_yester)
if len(data)>=23:
stk_month=data['adjclose'].iat[-23]
df.loc[tickers[i],'1ヶ月']='{:.2%}'.format((stk_today-stk_month)/stk_month)
if len(data)>=5:
stk_week=data['adjclose'].iat[-5]
df.loc[tickers[i],'1週間']='{:.2%}'.format((stk_today-stk_week)/stk_week)
quot = si.get_quote_table(tickers[i], dict_result = True)
df.loc[tickers[i],'時価総額']=""
df.loc[tickers[i],'PER']=0
if('Market Cap' in quot):
df.loc[tickers[i],'時価総額']=quot['Market Cap']
if('PE Ratio (TTM)' in quot):
df.loc[tickers[i],'PER']=quot['PE Ratio (TTM)']
fig = go.Figure(data=[go.Table(
header=dict(values=header, line_color='black', fill_color='white',
align='center', font_size=16, height=30),
cells=dict(values=[tickers, df['現在値'], df['出来高'], df['時価総額'],
df['PER'], df['高値下落'], df['年初来'], df['1ヶ月'],
df['1週間'], df['1日']],
line_color='black',
fill_color=[['rgb(235, 235, 235)', 'white']*(int(len(tickers)/2)+1)],
align=['center', 'right'],
font_size=16, height=30)
)],
)
title = title+ ' ('+data.index[-1].strftime('%Y/%m/%d')+')'
fig.update_layout(
title={'text': title, 'y': 0.9, 'x': 0.5},
font={ 'family': 'Noto Sans CJK JP', 'size': 16},
width=1100
)
fig.show()
以下が出力データです。
今回新しく get_quote_table を使ってますので、実行に多少時間がかかります。
マニュアル詳細は以下をご覧ください。
また、plotly のマニュアルやライブラリは以下の通りです。
以下の課題をお願いいたします。
課題
画像でリスト作成
銘柄が多い場合、画像が切れる為保存ができないと指摘を受けましたので、画像で作成するコードを作りました。表出力部分のみ変更しておりますので、以下のコードを使ってみてください。また、パーセント表示部分はプラス、マイナスで色を付けました。以下のコードをお使いください。
import sys
sys.path.append('/content/drive/MyDrive/module')
import pandas as pd
import yahoo_fin.stock_info as si
import plotly.graph_objects as go
tickers = ['VOO', 'TWTR', 'AMZN', 'OTLY', 'META', 'TSLA', 'NVDA']
header = ['Ticker','現在値', '出来高', '時価総額', 'PER','高値下落',
'年初来', '1ヶ月', '1週間', '1日']
title = "ウォッチリストデータ"
df=pd.DataFrame()
for i in range(len(tickers)):
data = si.get_data(tickers[i])
df.loc[tickers[i],'Ticker']=tickers[i]
stk_today=data["adjclose"].iat[-1]
df.loc[tickers[i],'現在値']='$%.2f'%(stk_today)
vol_today=data["volume"].iat[-1]
df.loc[tickers[i],'出来高']=vol_today
stk_max=data['adjclose'].max()
df.loc[tickers[i],'高値下落']='{:.2%}'.format((stk_today-stk_max)/stk_max)
if '2020-12-31' in data.index:
stk_yend=data.loc['2021-12-31','adjclose']
df.loc[tickers[i],'年初来']='{:.2%}'.format((stk_today-stk_yend)/stk_yend)
if len(data)>=2:
stk_yester=data['adjclose'].iat[-2]
df.loc[tickers[i],'1日']='{:.2%}'.format((stk_today-stk_yester)/stk_yester)
if len(data)>=23:
stk_month=data['adjclose'].iat[-23]
df.loc[tickers[i],'1ヶ月']='{:.2%}'.format((stk_today-stk_month)/stk_month)
if len(data)>=5:
stk_week=data['adjclose'].iat[-5]
df.loc[tickers[i],'1週間']='{:.2%}'.format((stk_today-stk_week)/stk_week)
quot = si.get_quote_table(tickers[i], dict_result = True)
df.loc[tickers[i],'時価総額']=""
df.loc[tickers[i],'PER']=0
if('Market Cap' in quot):
df.loc[tickers[i],'時価総額']=quot['Market Cap']
if('PE Ratio (TTM)' in quot):
df.loc[tickers[i],'PER']=quot['PE Ratio (TTM)']
#########################################################################
# 表作成
#########################################################################
import IPython
from PIL import Image, ImageDraw, ImageFont
import os
output_dir = '/content/drive/MyDrive/output/'
if not os.path.isdir(output_dir): os.makedirs(output_dir)
font_title = ImageFont.truetype("/content/drive/MyDrive/module/japanize_matplotlib/fonts/ipaexg.ttf", 18)
font_head = ImageFont.truetype("/content/drive/MyDrive/module/japanize_matplotlib/fonts/ipaexg.ttf", 16)
font_txt = ImageFont.truetype("/content/drive/MyDrive/module/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf", 16)
#########################################################################
# 初期設定
# Xサイズ
x_width = [80,90,110,100,85,85,85,85,85,85]
y_width = 30
title_y = 50
x_buff = 10
# 色を付けたいセル(プラスは青、マイナスは赤)
cell_pct = ['高値下落','年初来','1ヶ月','1週間','1日']
#########################################################################
im = Image.new('RGB', (sum(x_width)+x_buff*2, y_width*(len(tickers)+1)+title_y+10), "white")
draw = ImageDraw.Draw(im)
#### タイトル 部分 ####
draw.text((sum(x_width)/2-301/2, 10),title+ ' ('+data.index[-1].strftime('%Y/%m/%d')+')',
(42,63,95),font=font_title)
#### ヘッダー 部分 ####
xpos=x_buff
ypos=title_y
for i in range(len(header)):
draw.rectangle([(xpos, ypos), (xpos+x_width[i], ypos+y_width)], fill=(221,237,255), outline=(0,0,0), width=1)
draw.text((xpos+10, ypos+5),header[i], (42,63,95),font=font_head)
xpos=xpos+x_width[i]
#### データ 部分 ####
for t in range(len(tickers)):
ticker = tickers[t]
xpos=x_buff
ypos=ypos+y_width
for i in range(len(header)):
draw.rectangle([(xpos, ypos), (xpos+x_width[i], ypos+y_width)], outline=(0,0,0), width=1
, fill=((255,255,255) if t % 2 == 0 else (235,235,235)))
# 色付け #########
if(header[i] in cell_pct):
if (str(df.loc[ticker,header[i]])[:1]=='-'):txt_color="red"
else:txt_color="blue"
else:
txt_color=(42,63,95)
draw.text((xpos+5, ypos+5),str(df.loc[ticker,header[i]]), txt_color,font=font_txt)
xpos=xpos+x_width[i]
# 太枠形成 ##############################################################
xpos=x_buff
ypos=title_y
# 外太枠 ######################################
draw.rectangle([(xpos, ypos), (xpos+sum(x_width), ypos+y_width*(len(tickers)+1))], outline=(0,0,0), width=2)
# ヘッダ太枠 ##################################
draw.rectangle([(xpos, ypos), (xpos+sum(x_width), ypos+y_width)], outline=(0,0,0), width=2)
# 他太枠作成 ##################################
bold_fm='現在値'
bold_to='PER'
draw.rectangle([(xpos+x_width[header.index(bold_fm)-1], ypos), (xpos+sum(x_width[header.index(bold_fm)-1:header.index(bold_to)+1])
, ypos+y_width*(len(tickers)+1))], outline=(0,0,0), width=2)
# 出力 ##############################################################
im.save(output_dir+'list.png')
IPython.display.Image(output_dir+'list.png')
#########################################################################
このような出力になります。
雑談
本日は以上です。今週はチャート、表を作ってみてますが、来週からは実際のデータどりの詳細を説明していく予定です。また、現在メンバーは150名ぐらいですが、サポートはそんなに大変ではなさそうですので、追加サークルメンバーも募集したいと思います。参加した方はツイッターのアカウントにDMしてください。
ここから先は
¥ 100
サポートいただけますと、うれしいです。より良い記事を書く励みになります!