J-REITのキャピタルリターン、インカムリターン、リスクをPlotlyの3Dバブルチャートで比較
noteはhtmlもiframeも埋め込みできないんですね...
残念。仕方ないのでリンクから飛んで確かめてみてください...
このコードは、http://www.japan-reit.com からスクレイピングして取得したデータと株価を元に、J-REIT全銘柄のキャピタルリターン、インカムリターン、リスク(ボラティリティ・標準偏差)を比較できるインタラクティブな3Dバブルチャートを作成します。
完成したものは以下のリンクから見られます。
import pandas as pd
import numpy as np
from bs4 import BeautifulSoup
from pandas import Series, DataFrame
import requests
import urllib
import YahooFinanceSpider as y
import datetime
import plotly.offline as po
import plotly.graph_objs as go
import plotly.figure_factory as ff
import math
import codecs
import io
from datetime import timedelta
from plotly.offline import iplot
from plotly.graph_objs import Scatter, Figure, Layout, Histogram
urls = []
soups = []
base_url = 'http://www.japan-reit.com/meigara/'
# 銘柄コード
codes = [8951,8952,8953,8954,8955,8956,8957,8958,8960,
8961,8963,8964,8966,8967,8968,8972,8975,8976,
8977,8979,8984,8985,8986,8987,3226,3227,3234,
3249,3269,3278,3279,3281,3282,3283,3287,3290,
3292,3295,3296,3298,3451,3309,3453,3455,3459,
3462,3463,3466,3468,3470,3471,3472,3473,3476,
3478,3481,3487,3488,3492,3493,2971,2972,2979]
# 銘柄コードをurlに埋め込む
for i in codes:
url = urllib.parse.urljoin(base_url, str(i) +"/")
urls.append(url)
# beautifulsoupでparseする
for v in urls:
res = requests.get(v)
soup = BeautifulSoup(res.content, 'html.parser')
soups.append(soup)
# titleの取得
titles = []
for t in soups:
brand = t.title.string[:-40]
titles.append(brand)
# 分配金利回りの取得
div_int_rates = []
for d in soups:
try:
table_d = d.find_all("table", {"class":"meigara-table"})[0]
div_int_rate = table_d.find_all("td", {"class":"r"})[2].string[:-9]
div_int_rates.append(div_int_rate)
except:
div_int_rates.append('0')
# 時価総額の取得
capitals = []
for c in soups:
try:
table = c.find_all("table", {"class":"meigara-table"})[0]
capital = table.find_all("td", {"class":"r"})[1].string[:-3]
capitals.append(capital)
except:
capitals.append('0')
# 時価総額をint型に変換し、バブルサイズをいい感じにするために係数で割って調整
rmcs = []
for rmc in capitals:
r = round(float(rmc.replace(',', ''))) / 25000
rmcs.append(r)
# DataFrameに格納
df = pd.DataFrame([titles, codes, div_int_rates, capitals]).T.rename(
columns={0: '銘柄名', 1: '銘柄コード', 2:'分配金利回り[%]', 3:'時価総額[百万円]'})
# j-reit.comから抽出したデータ
jrc_data = df.T
# 90日間のデータを使う
end_time = datetime.date.today()
start_time = end_time - timedelta(days = 90)
# クローラーを作る
c = y.Crawler()
# 終値の取得
prc = [[] for i in range(len(codes))]
for i in range(len(codes)):
for yf in c.get_price(str(codes[i]), start_time, end_time, y.DAILY):
prc[i].append(yf.close)
row_df = pd.DataFrame(prc).T
# 日付の取得
date = []
for yf in c.get_price(str(codes[0]), start_time, end_time, y.DAILY):
date.append(yf.date)
# インデックスを日付に、カラムを銘柄名に
row_df.index = date
row_df.columns = titles
# 値をfloat型に
df = row_df.astype(float)
# キャピタルリターン算出の為変化率のdataframeを用意する
pct_df = df.iloc[::-1].pct_change().dropna()
# キャピタルリターンを'算術平均'にて算出
# 本来なら'幾何平均'を使うべき
annual_return = pct_df.mean() * 3650000 / len(df.index)
X = annual_return
# インカムリターンの算出(スクレイピングデータより)
inc_ret = pd.Series(jrc_data.iloc[2])
Y = inc_ret
# リスク(標準偏差)の算出
std = pct_df.std()
Z = std
# チャートの描画
from plotly.graph_objs import Scatter3d
from plotly.offline import init_notebook_mode, iplot
init_notebook_mode() # <- Notebook出力にはこの1行が必要
scatter = Scatter3d(x=X, y=Y, z=Z,
mode='markers',
text=X.index,
marker=dict(size=rmcs, # マーカーのサイズ
color=Z, # 色分けに使う数値(任意の数値を指定可)
colorscale='Magma', # 色のパターン
showscale=True) # カラーバーを表示
)
# レイアウトの指定
# バブルサイズの調整
start, end = 15000, 1200000
fig = go.Figure(scatter)
fig.update_layout(scene = dict(
xaxis_title = 'x:年間平均リターン[%]',
yaxis_title = 'y:配当利回り[%]',
zaxis_title = 'z:標準偏差'
),
width=750,
height=650,
margin=dict(r=20, b=10, l=10, t=10)
)
iplot(fig) # <- Notebookに出力するにはiplot関数を使うtd
Plotly Chart Studioでオンライン上で表示
chart studioでオンライン上で表示する為にはchart studioの登録とapi keyの設定が必要になります。
import chart_studio.plotly as py
py.plot(fig, filename='JREIT bubble chart')
これでこんなかっこいいバブルチャートができます。
自分の手で動かしてみよう!
この記事が気に入ったらサポートをしてみませんか?