J-REITのキャピタルリターン、インカムリターン、リスクをPlotlyの3Dバブルチャートで比較
このコードは、http://www.japan-reit.com からスクレイピングして取得したデータと株価を元に、J-REIT全銘柄のキャピタルリターン、インカムリターン、リスク(ボラティリティ・標準偏差)を比較できるインタラクティブな3Dバブルチャートを作成します。
完成したものは以下のリンクから見られます。
https://chart-studio.plotly.com/~hiroshimaeasyryo/255/#/
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関数を使う<200b>
Plotly Chart Studioでオンライン上で表示
chart studioでオンライン上で表示する為にはchart studioの登録とapi keyの設定が必要になります。
import chart_studio.plotly as py py.plot(fig, filename='JREIT bubble chart')
ぜひ自分の手で動かしてみて欲しい。