【Python】2資産ポートフォリオのリスクリターンマップを作る


TwitterでSPXLとTMFを組み合わせたポートフォリオのリスクリターンマップを紹介しました。

ここに、そのグラフを作るためのコードを保存しておきます。

あらかじめ以下のサイトからTMF,SPXL,VTIのcsvファイルを取得しておきます(期間はMAX)。
(本当は、取得するcodeをかければ良いのですが・・・)

TMF: https://www.nasdaq.com/market-activity/funds-and-etfs/tmf/historical
SPXL: https://www.nasdaq.com/market-activity/funds-and-etfs/spxl/historical
VTI: https://www.nasdaq.com/market-activity/funds-and-etfs/vti/historical

それぞれ、"TMF.csv", "SPXL.csv", "VTI.csv"というファイル名で保存しておきます。

1. ライブラリの読み込み。

#Invite frends to the party...
import numpy as np
import pandas as pd
from datetime import datetime
import seaborn as sns
sns.set()
import matplotlib.pyplot as plt
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()

2. csvファイルを1つのDataFrameにまとめる関数

def make_df(etfs):
    df = pd.DataFrame()
    for etf in etfs:
        csvfile = etf +'.csv'
        csv_data = pd.read_csv(csvfile)
        csv_data.Date = pd.to_datetime(csv_data.Date)
        csv_data = csv_data.set_index('Date')
        csv_data= csv_data.rename(columns={' Close/Last': etf})
        df[etf] = csv_data[etf]
        df = df.sort_index().dropna()
    return df

3. 分散ポートフォリオ指数をDataFrameに追加する関数

def make_port_df(df):
    #リターン算出
    rtn = (df /  df.shift(1) -1).fillna(0)

    #各比率のポートフォリオデータを作成
    for w in [9, 8, 7, 6, 5, 4, 3, 2, 1]:
        rtn['SPXL'+str(w)+' : TMF'+str(10-w)] =rtn['SPXL']*(w/10) + rtn['TMF']*(1-w/10)

    rtn += 1
    df = rtn.cumprod()

    return df 

4. リスクリターンマップを作成する関数

def rr_map(df):
    #月次リターン算出
    dfm = df.resample('M').ffill()
    m_rtn = (dfm /  dfm.shift(1) -1).dropna()

    #リスク算出
    std = (m_rtn.std())*(12**0.5)

    #年率リターン算出
    cum = m_rtn+1
    a_rtn = (cum.product())**(12/len(m_rtn))-1

    #リスクリターンマップ作成
    plt.figure(figsize=(6, 6))
    for asset in list(a_rtn.index):
        plt.scatter(x = std[asset], y = a_rtn[asset],label = asset)
    plt.xlabel('Risk')
    plt.ylabel('Return')
    plt.xlim(0,std.max()*1.1)
    plt.ylim(0,a_rtn.max()*1.1)
    plt.legend(loc = 'best')
    plt.title('Risk Return Map')

    plt.savefig('rr_map.png',bbox_inches="tight")

4. 上記関数を実行する

etfs = ['SPXL','TMF','VTI']
df = make_df(etfs)
df = make_port_df(df)
rr_map(df)

↓このグラフが表示される。

5. まとめ

SPXLとTMFをだいたい半分ずつ持つことで、リスクリターン特性がVTIより優れたポートフォリオになりそうです(投資は自己責任でおねがいします)。

6.次の課題

  • 複数資産の分散ポートフォリオ