ドルコスト平均法の検証
私は、投資信託を毎日xxx円購入するという積立投資をしています。
時間軸方向の分散投資です。
今までは、毎月1回購入よりも、毎日購入した方が、リスク分散はできているのかなと安易に思っていたのですが、ちゃんと検証してみたいと思います。
ドルコスト平均法が、リスク分散に有利というのはよく言われていますが、毎日購入と毎月購入のどちらに軍配が上がるのでしょうか。
検証する内容は以下です。
- 毎日購入、毎月1回購入 (1日, 11日, 21日の3パターン) で比較する。非営業日の場合は、お休み明けの営業日に購入する。
- 日経平均株価 (N225) と ダウ・ジョーンズ工業株価平均 (DJI) で比較する。
- 投資期間は 5年間 とする。
株価データの取得
投資期間を5年間としたので、2017年6月1日 から 2022年5月31日 まで の 日経平均株価 (N225) と NYダウ (DJI) の株価を取得します。
pandas-datareader を使います。
YahooDailyReader の公式ドキュメント のリンクも書いておきます。
from pandas_datareader.yahoo.daily import YahooDailyReader
date_start = pd.to_datetime('2017-06-01 12:00:00', utc=True)
date_end = pd.to_datetime('2022-05-31 12:00:00', utc=True)
df_n225 = YahooDailyReader(
symbols='^N225',
start=date_start,
end=date_end,
).read()
df_dji = YahooDailyReader(
symbols='^DJI',
start=date_start,
end=date_end,
).read()
以下のようなデータが取得できます。
Date
2017-06-01 19887.660156 19686.320312 19692.160156 19860.029297 103500000.0 19860.029297
2017-06-02 20239.810547 19967.000000 19970.230469 20177.279297 150400000.0 20177.279297
2017-06-05 20224.539062 20104.130859 20135.419922 20170.820312 99100000.0 20170.820312
2017-06-06 20152.949219 19948.019531 20122.259766 19979.900391 102000000.0 19979.900391
2017-06-07 20023.240234 19908.070312 19951.679688 19984.619141 99200000.0 19984.619141
終値で株価チャートを描いてみます。円とドルで単位は違うのですが、30,000 前後の価格なので、一つのグラフに描いてしまいます。
df_n225['Adj Close'].plot(label='N225 Adjust Close')
df_dji['Adj Close'].plot(label='DJI Adjust Close')
plt.legend()
plt.grid(color='gray', linestyle='--', alpha=0.5)
plt.show()
ドルコスト平均法で積立投資のシミュレーション
評価方法は、最終日 2022年5月31日 の終値で算出した評価額を使用します。
つまり、最終日の終値 ✕ 購入済株数 = 評価額 の高い方が勝ちです。
毎日購入の場合は、毎日千円購入します。NYダウの場合は1000ドル購入とします。
購入株数 = 千円 ÷ その日の終値 です。
毎月購入の場合は、その月の営業日数 ✕ 千円 が、その月の購入代金です。
購入株数 = 購入代金 ÷ 指定営業日の終値 です。
毎日購入の場合の 最終日の評価額 と 元金からの増加率 の算出式です。
def calc_dollarcost_daily(df, unit):
total_shares = (1000/df['Adj Close']).cumsum().values[-1]
final_price = df.loc[df.index[-1], 'Adj Close']
final_date_str = df.index[-1].strftime('%Y/%m/%d')
total_invest = 1000 * len(df)
print('[毎日購入] {}評価額: {:,.2f}{} 増加率: {:.2f}%'
.format(
final_date_str,
final_price * total_shares,
unit,
((final_price * total_shares) / total_invest - 1) * 100,
))
return
毎月1回購入の場合の 最終日の評価額 と 元金からの増加率 の算出式です。
import pandas.tseries.offsets as offsets
def calc_dollarcost_monthly(df, buy_day, unit):
df['year'] = df.index.year
df['month'] = df.index.month
df['day'] = df.index.day
total_shares = 0
for year in np.unique(df['year'].values):
for month in np.unique(df[df['year'] == year]['month'].values):
# この月の営業日数を算出する。
days = len(df[(df['year'] == year) & (df['month'] == month)])
# この月の購入代金を算出する。1000円✕営業日数。
purchase_amount = 1000 * days
# 購入指定日の終値を取得する。
# 購入指定日が営業日でない場合は、後ろへずらす。
for i in range(0, 10): # 指定日から10日以内に営業日はあるはず。
purchase_index = pd.Timestamp(year, month, buy_day) + offsets.Day(i)
if purchase_index in df.index:
# 購入指定日に最も近い営業日が見つかったら、抜ける。
break
purchase_price = df.at[purchase_index, 'Adj Close']
# この月に購入した株数を算出する。
purchase_shares = purchase_amount / purchase_price
total_shares += purchase_shares
final_price = df.loc[df.index[-1], 'Adj Close']
final_date_str = df.index[-1].strftime('%Y/%m/%d')
total_invest = 1000 * len(df)
print('[毎月{:>2}日に購入] {}評価額: {:,.2f}{} 増加率: {:.2f}%'
.format(
buy_day,
final_date_str,
final_price * total_shares,
unit,
((final_price * total_shares) / total_invest - 1) * 100,
))
return
以下のように、関数を呼び出します。
calc_dollarcost_daily(df_n225, unit='円')
calc_dollarcost_monthly(df_n225, buy_day=1, unit='円')
calc_dollarcost_monthly(df_n225, buy_day=11, unit='円')
calc_dollarcost_monthly(df_n225, buy_day=21, unit='円')
print('合計投資額: {:,}円' .format(1000*len(df_n225)))
calc_dollarcost_daily(df_dji, unit='ドル')
calc_dollarcost_monthly(df_dji, buy_day=1, unit='ドル')
calc_dollarcost_monthly(df_dji, buy_day=11, unit='ドル')
calc_dollarcost_monthly(df_dji, buy_day=21, unit='ドル')
print('合計投資額: {:,}ドル' .format(1000*len(df_dji)))
シミュレーション結果
日経平均株価 (N255) の結果です。
成績は、毎月1日に購入、毎月11日に購入、毎日購入、毎月21日に購入 の順でした。
ちょっとショックでした。毎日購入が1位になる想定だったので。
計算時の端数処理の影響があるか (攻殻機動隊 S.A.C. 2nd GIG のクゼが使った技) と思い、毎日購入の関数をいじってみたのですが、影響は無さそうでした。
[毎月 1日に購入] 2022/05/31評価額: 1,425,612.61円 増加率: 17.05%
[毎月11日に購入] 2022/05/31評価額: 1,424,039.54円 増加率: 16.92%
[毎月21日に購入] 2022/05/31評価額: 1,419,850.40円 増加率: 16.57%
合計投資額: 1,218,000円
NYダウ (DJI) の結果です。
成績は、毎月1日に購入、毎月21日に購入、毎月11日に購入、毎日購入 の順でした。
[毎月 1日に購入] 2022/05/31評価額: 1,530,218.52ドル 増加率: 21.54%
[毎月11日に購入] 2022/05/31評価額: 1,522,395.41ドル 増加率: 20.92%
[毎月21日に購入] 2022/05/31評価額: 1,525,376.21ドル 増加率: 21.16%
合計投資額: 1,259,000ドル
5年間の積立投資シミュレーションの結果しか見ていませんが、これを受けて、毎日購入をやめ、複数の投資信託の購入日を分散させ、毎月1回購入 に切り替えるのもアリかと思いました。