【月初が安定】積立投資の購入タイミングについて検討

＜あらすじ＞
毎月積立投資を始めようとすると購入日を設定する必要があります。
一般的に毎月の積立日や頻度を変えてもドルコスト平均法によって、**長期的なリターンはほとんど変わらない**と言われています。

しかし、**毎月積立投資をする人が増えても同じでしょうか？**
・2018年1月からスタートした「つみたてNISA」の口座数が1年で1.6倍
・バンガードの「VTSAX」が同種のファンドで初めて運用資産が1兆ドルを上回る
など日本でも世界でもインデックス投資や積立投資が増え続けている。

ここで、**毎月積立投資をする人が増えるほど購入日が偏ったときの影響が大きくなる（顕著化する）のではないか**という疑問が生じました。

今回は毎月積立投資をする人の増加が値動きに偏りを生じさせていないかを検証します。
購入日が偏りやすい日にちを調査し、S&P500と日経平均株価の平均購入価格で比較しました。

＜結論＞
・**1日（月初）が最も安く購入可能**（期間が1年間のときは1%程度安い）
・期間が10,5年のときは**月末は0.1%程度購入価格が高い**

# 背景
## 積立投資の購入タイミング
「つみたてNISA」「ドルコスト平均法」「手軽」などの理由から投資信託への積立投資をしている人が多いです。
そこで、いざ毎月積立投資を行おうと思うと、購入日を設定する必要があります。
何日に設定するのがいいのかなと、「積立投資　積立日」で検索すると
・[積立投資に驚きの結果　購入頻度でリターンに大差なし](https://style.nikkei.com/article/DGXMZO17172260R00C17A6000000)
・[「月初の株高」　投信積み立てのベストタイミングは？](https://style.nikkei.com/article/DGXMZO28484710T20C18A3000000/)
など、投資信託別や積立頻度を長期的に検証した記事が複数ありますが、
いずれも結論としては**長期なら毎日、毎週、毎月、隔月もリターンはほとんど変わらない**です。

確かに過去20年近くは変わらなかったとして、**今後積立投資をする人が増えても同じなのか**疑問に感じました。

## 増えるつみたてNISA/証券口座/インデックス投資
▼増えるつみたてNISA：日本証券業協会 NISA口座開設・利用状況結果(2020/6/30)より
![SnapCrab_NoName_2020-12-27_17-15-2_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906836/fadc138f-43e0-18e1-98b5-820f887a1cc0.png)
▼ 増える証券口座：女性と若年層、そして初心者層の取り込みにより新規口座開設者が増える
>楽天証券は12月15日、証券口座数が500万に達したと発表した。コロナ禍の中、オンライン証券の利用者は増加しており、後押しとなった。200万口座から300万口座へは35カ月、300万から400万へは15カ月かかっていたが、400万から500万口座へは9カ月での達成となった。
>引用：[楽天証券500万口座突破　9カ月で100万口座増](https://www.itmedia.co.jp/business/articles/2012/15/news144.html)

▼増えるインデックス投資：VTSAXが運用資産1兆ドルを突破
>バンガード・トータル・ストック・マーケット・インデックス・ファンドの運用資産はミューチュアルファンドと上場投資信託（ＥＴＦ）の両方を含め、11月30日時点で１兆400億ドル。これは過去30年にわたりインデックス投資が増えているという証しだ。
>引用：[バンガードの株式ファンド、運用資産１兆ドル突破－同種ファンドで初](https://www.bloomberg.co.jp/news/articles/2020-12-16/QLEHUOT1UM0X01)

## 毎月積立投資をする人が増えると
▼ある投資信託において1ヵ月の資金流入が完全にランダムの場合
![SnapCrab_NoName_2020-12-27_20-18-36_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906836/ac242971-5351-8466-0439-8eb49d28195f.png)
▼ある投資信託において1ヵ月の中で資金流入が完全にランダムかつ**15日だけ10%増加**した場合
![SnapCrab_NoName_2020-12-27_20-19-10_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906836/0488722e-590c-1967-93ed-9baec953da4b.png)
※ 簡略のために乱数の範囲は0~1（確率は一様）

ここで「試行回数⇒毎月積立投資をする人数」とすると
**毎月積立投資をする人が増えるほど購入日が偏ったときの影響が大きくなる（顕著化する）**のではないか
という考えが今回の検証のきっかけです。

## 考えられる購入日
多くの証券会社は積立日を自分で決められます。

2018年2月25日の記事ですが[こちら](https://www.nikkei.com/article/DGKKZO27363960U8A220C1EA2000)より
松井証券の積立口座の買付日設定ランキング
第1位： 1日
第2位： 月末
第3位： 10日
第4位： 25日
第5位： 15日
第6位： 20日
第7位： 5日
第8位： 27日
第9位： 26日
第10位： 28日

また、
・iDeCo：毎月26日に引き落とされ13営業日目の10時に発注される（毎月15日あたり）
・日本の給料日：5日、10日、15日、20日、25日、30日が多く、特に25日が多い
・世界の給料日：アメリカは第2・第4金曜日の2回、中国/ヨーロッパは月末、インドは月初

以上より
購入日として**1日 / 月末 / 五十日（5の倍数の日）**が多いと考えます。

# 検証内容
検証する購入日のパターンを以下とします。

*  1日
* 14日
* 15日
* 24日
* 25日
* 月末

購入方法はドルコスト平均法で毎月一定の金額を購入するとします。
6つのタイミングで約定したときの**平均購入価格を過去20年/10年/5年/1年**で比較します。
検証対象は多くの投資信託やETFの指標とされる**S&P500**と比較のために**日経平均株価**の2つです。

購入日として想定される1日 / 月末 / 五十日（5の倍数の日）よりも**前日である14,24日の方が平均購入価格が低くなる**のではないかと予想しました。
比較する値が平均購入価格のため低いほど利益が得られることになります。
また、今回の検証では購入日＝約定日とし、為替変動については考えません。

※ 算出方法とプログラムは記事の最後に記載します

# 結果
【パラメータ】
検証期間：20,10,5,1年
対象銘柄：S&P500,日経平均株価
約定日：1,14,15,24,25日,月末
※購入日が休業日の場合は翌営業日
※データは2020年12月26日までを使用（例：1年なら2019年1月～）

【結果】
下に検証結果の表を記載してありますが、ざっとまとめると
・全約定日の中で**1日（月初）が最も安く購入可能**（期間が1年間のときは1%程度安い）
・期間が10,5年のときは他の日に比べて**月末は0.1%程度購入価格が高い**
・約定日として多いと想定した日とその前日である14,24日の間にめぼしい特徴は確認できない
・20年間毎月積立ならばいつ購入しても平均購入価格は変わらない
　

▼平均購入価格
![result_ave_price.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906836/d6604d17-de8f-d7da-7697-f85ae9bdbe6e.png)

▼平均購入価格の約定日1日に対する比率（プラスの場合1日よりも高い）
![result_ave_price_rate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906836/1e2c1112-adff-bab5-7109-5551f4e9e3c9.png)

▼平均購入価格の約定日1日に対する比率のグラフ（プラスの場合1日よりも高い）
![result_all.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906836/a17248cf-2f13-89d2-84fd-28ce592daada.png)

## おまけ（1~31日全てのデータ）
▼平均購入価格の約定日1日に対する比率のグラフ（プラスの場合1日よりも高い）
![omake.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906836/e85afb13-2afb-7c56-f02e-be95cde00ab6.png)


# まとめ
毎月積立投資をしようと思うと購入タイミングについて一度は気になるのではないでしょうか。
一般的に毎月の積立日や頻度を変えてもドルコスト平均法によって、長期的なリターンはほとんど変わりません。
しかし、**今後積立投資をする人が増えることによって購入日が偏ったときの影響が大きくなるではないか**と考えました。
多い購入日として1日 / 月末 / 五十日（5の倍数の日）が候補となり、その前日の方が平均購入価格が低くなると予想しました。
結果は1日（月初）が最も安く購入可能となり、「**購入日として最も多いと想定した日が最も安く購入できる**」が得られました。

今回の検証でもやはり長期的なリターンは購入日タイミングによってほとんど変わらないことが確認できた一方で、10,5年の期間では初日から月末になるにつれて購入価格は上がることがわかりました。一定で上昇するならば、早め早めに購入した方が安くで購入できることになるのかもしれません。

以上より、**特にこだわりがなければ1日に購入日を設定することをお勧めします。**
<font color="DarkGray" size=1>
おまけの結果を見ると検証期間1年において11日付近で山が現れています。
この辺りで購入タイミングが偏っている可能性が...
</font>

# 次は
急騰中の仮想通貨について何かしら検証してみたいと思います。
仮想通貨はビットコインがアルトコインの先行指数になっていることが明らかなためデータを使って詳しく見てみたいと考えています。
またビットコインとの相関だけではなかなか購入の決定要因としては弱いため、いくつかの指標からビットコインとアルトコインの関係を調査できたらと思います。

今後の予定
・ビットコインとアルトコインの関係を調査
・コロナ感染者が増える（or緊急事態宣言）と上昇する銘柄の調査


# 算出方法
## 平均購入価格
【ドルコスト平均法】
価格が変動する金融商品を常に一定の金額で、かつ時間を分散して定期的に買い続ける手法です。
これによりリスクとリターンを平準化し、大きな値動きの影響を受けにくくします。

ドルコスト平均法での平均購入価格は購入価格の**調和平均**で求められます。
正の実数$a_1,a_2,...,a_n$の調和平均$H$は次式で表されます。

```math
H=\frac{1}{\frac{1}{n}(\frac{1}{a_1}+\frac{1}{a_2}+\dots+\frac{1}{a_n})}
```

毎月の購入金額を$m$、全部で$n$回購入したうちの$i$回目に購入する株価を$p_i$とすると、その時の購入株数は$m/p_i$であり、平均購入価格は以下となる
$$平均購入価格=\frac{トータルの購入金額}{トータルの購入株数}$$
よって

```math
\begin{align}
平均購入価格&=\frac{nm}{\frac{m}{p_1}+\frac{m}{p_2}+\dots+\frac{m}{p_n}}\\
&=\frac{1}{\frac{1}{n}(\frac{1}{p_1}+\frac{1}{p_2}+\dots+\frac{1}{p_n})}
\end{align}
```

Pythonでは以下で算出できる。

```Python:
from statistics import harmonic_mean

harmonic_mean(price)
```

## プログラム

```Python:
import pandas as pd
import numpy as np
from statistics import harmonic_mean

# パラメータ
code="^GSPC"
period = 20

# 用意したデータの読み込み
data = pd.read_csv(code+".csv",index_col=0, parse_dates=True)
start = 2020-period+1
data = data[str(start):]

# 平均購入価格算出のためのデータフレーム作成
row = range(1,32)
col = []
for y in range(start,2021,1):
    for m in range(1,13):
        col.append("{:0=4d}-{:0=2d}".format(y,m))
temp = pd.DataFrame(index=row,columns=col)

# 作製したデータフレームにデータ割り振り
for i in range(len(data.index)):
    y = data.index[i].year
    m = data.index[i].month
    d = data.index[i].day
    temp.at[d,"{}-{:0=2d}".format(y,m)] = data.Close[i]
    
# 平均購入価格を算出
price = []
ave_price = []
for day in range(1,32):
    for i in range(len(temp.columns)):
        d = day-1
        count = 0
        # データがない場合は次の日の値を使用
        while (np.isnan(temp.iat[d,i])):
            d+=1
            if(d>=31):
                count+=1
                d = day-1-count
        else:
            price.append(temp.iat[d,i])
    
    # 調和平均で平均購入価格を算出
    ave_price.append(harmonic_mean(price))
    prece = []

print(ave_price[i])
```