Python
highcharts
Finance
Jupyter

Python-Highchartsのドリルダウンでポートフォリオを可視化する

More than 1 year has passed since last update.


Python-Highchartsのドリルダウンでポートフォリオを可視化する

投資信託のポートフォリオの可視化にPython-Highchartsを試してみました.

Python-HighchartsはJavaScriptの可視化ライブラリHighchartsのPythonのラッパーです.

Python-Highchartsを使うとインタラクティブに操作できるグラフを作成できます.


インストール

Python-Highchartsをインストールします.

pip install python-highcharts

なお,今回は,Python3.6.0です.


準備

はじめに,Python-Highchartsと今回使うライブラリをインポートします.

from itertools import product  # 投資比率パターン生成用

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from highcharts import Highchart
%matplotlib inline

ここでは,伝統的な4つの資産,国内株式,国内債券,外国株式,外国債券のインデックスに連動する投資信託への資産配分を考えます.


  • 国内株式インデックスファンド

  • 国内債券インデックスファンド

  • 外国株式インデックスファンド

  • 外国債券インデックスファンド

事前にこれらの資産の時系列データから週次のリターンの平均と共分散行列を計算しておきます.(*数値は一例です.用いた数値に一切責任は負いません.)

asset_list = ['国内株式', '国内債券', '外国株式', '外国債券']

mean = pd.Series([0.001487, 0.000283, 0.001905, 0.000723], index=asset_list, name='expected return')

mean

国内株式    0.001487

国内債券 0.000283
外国株式 0.001905
外国債券 0.000723
Name: expected return, dtype: float64

cov = pd.DataFrame([[7.95021e-04, -2.4461e-05, 6.06600e-04, 2.00937e-04],

[ -2.4461e-05, 8.485e-06, -2.1082e-05, -9.016e-06],
[ 6.06600e-04, -2.1082e-05, 8.82778e-04, 2.15332e-04],
[ 2.00937e-04, -9.016e-06, 2.15332e-04, 1.38414e-04]]
, index=asset_list, columns=asset_list)
cov




国内株式
国内債券
外国株式
外国債券




国内株式
0.000795
-0.000024
0.000607
0.000201


国内債券
-0.000024
0.000008
-0.000021
-0.000009


外国株式
0.000607
-0.000021
0.000883
0.000215


外国債券
0.000201
-0.000009
0.000215
0.000138

シャープレシオ(リスクフリーレートは考慮しない)も計算してみます.

std = pd.Series(np.sqrt(np.diag(np.array(cov))), index=asset_list, name='expected volatility')

df = pd.concat([mean, std], axis=1)
df['sharpe ratio'] = mean / std
df.T




国内株式
国内債券
外国株式
外国債券




expected return
0.001487
0.000283
0.001905
0.000723


expected volatility
0.028196
0.002913
0.029712
0.011765


sharpe ratio
0.052738
0.097154
0.064116
0.061454

4つの資産の平均と標準偏差をmatplotlibでプロットしてみます.

plt.figure(figsize=(10, 6))

plt.scatter(std, mean, c=df.loc[:, 'expected return']/df.loc[:, 'expected volatility'], marker='o')
plt.grid(True)
plt.xlim(-0.005, 0.035)
plt.ylim(-0.00025, 0.002)
plt.xlabel('expected volatility')
plt.ylabel('expected return')
plt.colorbar(label='Sharpe ratio')
#plt.savefig('.png')

output_12_1.png


matplotlibで可視化する(比較用)

投資比率のパターンをたくさん作り,ポートフォリオの期待リターンと標準偏差を計算します.


ランダムに作成した例とitertoolsを使った例を載せます.どちらか選択して実行してください.


  • ランダムに投資比率のパターンを作ってみる

投資比率のパターンをたくさん作り,ポートフォリオの期待リターンと標準偏差を計算します.

prets = []

pvols = []
weights_list = [] # highcharts用
for p in range(500):
weights = np.random.randint(low=0, high=11, size=len(asset_list))
weights = weights / np.sum(weights)
weights_name = [[_i, _j] for _i, _j in zip(asset_list, weights)] # highcharts用
weights_list += [weights_name] # highcharts用
prets.append(np.sum(mean * weights))
pvols.append(np.sqrt(np.dot(weights.T,np.dot(cov,weights))))

資産の組み合わせごとのリスク(標準偏差)と期待リターンをプロットし,色でシャープレシオの大きさを表します.

plt.figure(figsize=(10, 6))

plt.scatter(pvols, prets, c=np.array(prets)/np.array(pvols), marker='o')
plt.grid(True)
plt.xlim(-0.005, 0.035)
plt.ylim(-0.00025, 0.002)
plt.xlabel('expected volatility')
plt.ylabel('expected return')
plt.colorbar(label='Sharpe ratio')

output_19_1.png


  • itertoolsのproductを使って投資比率のパターンを作ってみる

投資比率のパターンをたくさん作ります.

weights = np.linspace(0, 1, 5)

weights = product(weights, repeat=4)
weights = pd.DataFrame(list(weights)[1:], columns=asset_list)
weights = weights.divide(weights.sum(axis=1), axis=0)
weights = weights.drop_duplicates()

ポートフォリオの期待リターンと標準偏差を計算します.

prets = list((weights * mean).sum(axis=1))

pvols = []
for _num, _ix in enumerate(weights.index):
w = weights.loc[_ix, :]
pvols += [np.sqrt(np.dot(w.T, np.dot(cov, w)))]

plt.figure(figsize=(10, 6))

plt.scatter(pvols, prets, c=np.array(prets)/np.array(pvols), marker='o')
plt.grid(True)
plt.xlim(-0.005, 0.035)
plt.ylim(-0.00025, 0.002)
plt.xlabel('expected volatility')
plt.ylabel('expected return')
plt.colorbar(label='Sharpe ratio')
#plt.savefig('efficient_frontier_matplotlib.png')

output_26_1.png


Highchartsで可視化する

Python-Highchartsを使うとインタラクティブで見栄えの良いグラフを作れます.

options = {

'title': {
'text': 'リスクとリターン'
},
'xAxis': {
'title': {
'text': 'リスク'
}
},
'yAxis': {
'title': {
'text': 'リターン'
}
},
'chart': {
'type': 'scatter',
},
'plotOptions': {
'scatter': {
'marker': {
'radius': 4,
'symbol': 'circle',
'states': {
'hover': {
'enabled': True,
'lineColor': 'rgb(100,100,100)'
}
}
},
'states': {
'hover': {
'marker': {
'enabled': False
}
}
},
'tooltip': {
'headerFormat': '<b>{series.name}</b><br>',
'pointFormat': 'risk :{point.x} <br> return:{point.y} '
}
}
}
}
H = Highchart()
H.set_dict_options(options)
data = list(zip(pvols, prets))
weights_data = []
for i in range(len(weights)):
weights_data += [{'x':data[i][0] ,'y': data[i][1], 'drilldown': 'portfolio'+str(i), 'name': 'portfolio'+str(i)}]
# 'drilldown'と'name'はドリルダウン用
weights_data
H.add_data_set(weights_data, 'scatter', 'ポートフォリオ')
H


投資比率をドリルダウンで表示してみる

各リスク・リターンのプロットを実現する投資比率が分かるドリルダウンを加えてみます.

# itertoolsを使ったとき用

weights_list = []
for _num, _ix in enumerate(weights.index):
weights_name = [[_i, _j] for _i, _j in zip(asset_list, weights.loc[_ix, :])]
weights_list += [weights_name]

for i in range(len(weights)):

H.add_drilldown_data_set(weights_list[i], 'pie', weights_data[i]['name'], name=weights_data[i]['name'])

H

hicharts2.gif

動作しない環境などありましたら,教えてもらえると助かります.


参考