【ドルコスト平均法】簡単なシミュレーションで遊んでみた🎵

新NISAが話題だが、そこで使われているドルコスト平均法がどういう性質を持つのか興味をもったので、簡単なシミュレーションをやってみた。
ドルコスト平均法の特徴
・長期の定額投資でメリットがある
・定額投資なので下がったときに口数が増加、上がったときは口数減少のため、利益が出やすい

それでは、これらの認識が正しいかシミュレーションをしてみる
手順は以下のとおり実施
・相場が上げているとき
・相場が下げているとき
・相場に上げ下げが同じ勾配で戻ったとき、
　　最初上げと最初下げのそれぞれの場合

今回は、ここまで、以下は要望があれば後日
・相場が最初に勾配が大きく下げ、その後ゆっくり戻ったとき
・逆に最初ゆっくり下げ、その後急激に戻ったとき
・最後に、期間を区切って特定の相場に対して、実際の動きをシミュレーションしてみる

### 実データ向けにlibを余分に定義

```lib.py
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import datetime as dt
from pandas_datareader import data
import yfinance as yf

import statsmodels.api as sm
from statsmodels.tsa.seasonal import STL
```

##　ここから本題

### 関数

```function.py
from datetime import datetime
from datetime import timedelta

start = datetime.strptime('202304', '%Y%m').date()
#datetime.strptime('2024-01-01', '%Y-%m-%d')
end   = datetime.strptime('202404', '%Y%m').date()
#datetime.strptime('2024-04-06', '%Y-%m-%d')
yosan = 1000

def daterange(_start, _end):
    for n in range((_end - _start).days):
        yield _start + timedelta(n)

def market_history(start, end):
    pd_stock = pd.DataFrame()
    i_list = []
    price_list = []
    kutisu_list = []
    cost_list = []
    j=0
    
    for i in daterange(start, end):
        market = 25000 + 15000/366*j  
        i_list.append(i)
        price_list.append(market)
        kutisu_list.append((yosan/market))
        cost_list.append(yosan)
        # print (i, market)
        j +=1
    pd_stock['date'] = i_list
    pd_stock['price'] = price_list
    pd_stock['kutisu'] = kutisu_list
    pd_stock['cost'] = cost_list
    return pd_stock

pd_stock = market_history(start, end)
pd_stock
```
参考
[【Python】指定した期間の連続した日付をだす](https://qiita.com/chatrate/items/21b5c83ecf9197e64299)

### 統計

```stat.py
pd_len = len(pd_stock)
pd_stock['price'].describe()
```

### コスト等

```cost.py
price_last = pd_stock['price'][pd_len-1]
kutisu_sum = pd_stock['kutisu'].sum()
cost_sum = pd_stock['cost'].sum()
print(price_last, kutisu_sum, cost_sum)
```

```joushou.py
	date	price	kutisu	cost
0	2023-04-01	25000.000000	0.040000	1000
1	2023-04-02	25040.983607	0.039935	1000
2	2023-04-03	25081.967213	0.039869	1000
3	2023-04-04	25122.950820	0.039804	1000
4	2023-04-05	25163.934426	0.039739	1000
...	...	...	...	...
361	2024-03-27	39795.081967	0.025129	1000
362	2024-03-28	39836.065574	0.025103	1000
363	2024-03-29	39877.049180	0.025077	1000
364	2024-03-30	39918.032787	0.025051	1000
365	2024-03-31	39959.016393	0.025026	1000
366 rows × 4 columns
```


### 出力

```output.py
jika = pd_stock['price'][pd_len-1] * kutisu_sum
print(cost_sum, kutisu_sum, jika, jika-cost_sum)
```
以下のとおり、約９万円の儲けです。

```儲かった.py
366000 11.475591883512736 458553.36419774254 92553.36419774254
```
### 下がったとき
コードの変更すべき部分は、以下の`market = 25000 - 15000/366*j  `部分だけです。

```function_geraku.py

def market_history(start, end):
    pd_stock = pd.DataFrame()
    i_list = []
    price_list = []
    kutisu_list = []
    cost_list = []
    j=0
    
    for i in daterange(start, end):
        market = 25000 - 15000/366*j  
        i_list.append(i)
        price_list.append(market)
        kutisu_list.append((yosan/market))
        cost_list.append(yosan)
        # print (i, market)
        j +=1
    pd_stock['date'] = i_list
    pd_stock['price'] = price_list
    pd_stock['kutisu'] = kutisu_list
    pd_stock['cost'] = cost_list
    return pd_stock

pd_stock = market_history(start, end)
pd_stock
```

```geraku.py
	date	price	kutisu	cost
0	2023-04-01	25000.000000	0.040000	1000
1	2023-04-02	24959.016393	0.040066	1000
2	2023-04-03	24918.032787	0.040132	1000
3	2023-04-04	24877.049180	0.040198	1000
4	2023-04-05	24836.065574	0.040264	1000
...	...	...	...	...
361	2024-03-27	10204.918033	0.097992	1000
362	2024-03-28	10163.934426	0.098387	1000
363	2024-03-29	10122.950820	0.098785	1000
364	2024-03-30	10081.967213	0.099187	1000
365	2024-03-31	10040.983607	0.099592	1000
366 rows × 4 columns
```
結果は、以下のとおり
めでたく、約１４万円の損失です。
しかし、さっきより、損失の大きいのが気になります。

```print(cost_sum, kutisu_sum, jika, jika-cost_sum).py
366000 22.327522546198075 224190.2878614151 -141809.7121385849
```
つまり、下げてあげた場合、ちゃんと利益できるのか、損失なのか？
同じように上げて下げた場合はどうなのか？

###　下げてあげた場合

```sgeage.py
mid_period  = datetime.strptime('202310', '%Y%m').date()
def market_history(start, end):
    pd_stock = pd.DataFrame()
    i_list = []
    price_list = []
    kutisu_list = []
    cost_list = []
    j=0
    market = 25000
    for i in daterange(start, mid_period):
        # market -= 15000/366 #*j  
        i_list.append(i)
        price_list.append(market)
        kutisu_list.append((yosan/market))
        cost_list.append(yosan)
        # print (i, market)
        j +=1
        print(j, i, market)
        market -= 15000/366 #*j
    print(j)    
    # j = 0
    for i in daterange(mid_period, end):
        market += 15000/366 #*j  
        i_list.append(i)
        price_list.append(market)
        kutisu_list.append((yosan/market))
        cost_list.append(yosan)
        # print (i, market)
        j +=1
        print(j, i, market)
    
    pd_stock['date'] = i_list
    pd_stock['price'] = price_list
    pd_stock['kutisu'] = kutisu_list
    pd_stock['cost'] = cost_list
    return pd_stock

pd_stock = market_history(start, end)
pd_stock
```

```結果code.py
pd_len = len(pd_stock)
pd_stock['price'].describe()
price_last = pd_stock['price'][pd_len-1]
kutisu_sum = pd_stock['kutisu'].sum()
cost_sum = pd_stock['cost'].sum()
print(price_last, kutisu_sum, cost_sum)
jika = pd_stock['price'][pd_len-1] * kutisu_sum
print(cost_sum, kutisu_sum, jika, jika-cost_sum)
```

```結果.py
25000.0 17.388605782099745 366000
366000 17.388605782099745 434715.14455249364 68715.14455249364
```
結果は、７万円弱儲かりました。

### 上げて下げた場合
結果は、以下のとおり約4.5万円の損失でした。
※簡単な解釈は、（当たり前ですが）**平均取得値はこの場合どうしても最後(現在)の株価と比較して高くなってしまっているためです**

```agesage結果.py
25000.0 12.812611337362927 366000
366000 12.812611337362927 320315.2834340732 -45684.71656592679
```

### まとめ
・ドルコスト平均法のふるまいを再現できた。
簡単に言うと、たとえドルコスト平均法といえども、下げてばかりの時期や上げても同じだけ下げたような場合（その期間にもよるが）は一時的にマイナスになることもあるということです。

さらに、多くの場合についてシミュレーションができますが、今回はこのあたりでやめておきます。
実際のNISA同様、月ごとの計算や実際のデータでのシミュレーションもできそうですが、別の機会にやることとし、本日はここまでとしておきます。

### 付録
ある出力

```
1 2023-04-01 25000
2 2023-04-02 25040.983606557376
3 2023-04-03 25081.967213114753
4 2023-04-04 25122.95081967213
5 2023-04-05 25163.934426229505
6 2023-04-06 25204.91803278688
7 2023-04-07 25245.901639344258
8 2023-04-08 25286.885245901634
9 2023-04-09 25327.86885245901
10 2023-04-10 25368.852459016387
11 2023-04-11 25409.836065573763
12 2023-04-12 25450.81967213114
13 2023-04-13 25491.803278688516
14 2023-04-14 25532.786885245892
15 2023-04-15 25573.77049180327
16 2023-04-16 25614.754098360645
17 2023-04-17 25655.73770491802
18 2023-04-18 25696.721311475398
19 2023-04-19 25737.704918032774
20 2023-04-20 25778.68852459015
21 2023-04-21 25819.672131147527
22 2023-04-22 25860.655737704903
23 2023-04-23 25901.63934426228
24 2023-04-24 25942.622950819656
25 2023-04-25 25983.606557377032
26 2023-04-26 26024.59016393441
27 2023-04-27 26065.573770491785
28 2023-04-28 26106.55737704916
29 2023-04-29 26147.540983606537
30 2023-04-30 26188.524590163914
31 2023-05-01 26229.50819672129
32 2023-05-02 26270.491803278666
33 2023-05-03 26311.475409836043
34 2023-05-04 26352.45901639342
35 2023-05-05 26393.442622950795
36 2023-05-06 26434.42622950817
37 2023-05-07 26475.409836065548
38 2023-05-08 26516.393442622924
39 2023-05-09 26557.3770491803
40 2023-05-10 26598.360655737677
41 2023-05-11 26639.344262295053
42 2023-05-12 26680.32786885243
43 2023-05-13 26721.311475409806
44 2023-05-14 26762.295081967182
45 2023-05-15 26803.27868852456
46 2023-05-16 26844.262295081935
47 2023-05-17 26885.24590163931
48 2023-05-18 26926.229508196688
49 2023-05-19 26967.213114754064
50 2023-05-20 27008.19672131144
51 2023-05-21 27049.180327868817
52 2023-05-22 27090.163934426193
53 2023-05-23 27131.14754098357
54 2023-05-24 27172.131147540946
55 2023-05-25 27213.114754098322
56 2023-05-26 27254.0983606557
57 2023-05-27 27295.081967213075
58 2023-05-28 27336.06557377045
59 2023-05-29 27377.049180327827
60 2023-05-30 27418.032786885204
61 2023-05-31 27459.01639344258
62 2023-06-01 27499.999999999956
63 2023-06-02 27540.983606557333
64 2023-06-03 27581.96721311471
65 2023-06-04 27622.950819672085
66 2023-06-05 27663.93442622946
67 2023-06-06 27704.918032786838
68 2023-06-07 27745.901639344214
69 2023-06-08 27786.88524590159
70 2023-06-09 27827.868852458967
71 2023-06-10 27868.852459016343
72 2023-06-11 27909.83606557372
73 2023-06-12 27950.819672131096
74 2023-06-13 27991.803278688472
75 2023-06-14 28032.78688524585
76 2023-06-15 28073.770491803225
77 2023-06-16 28114.7540983606
78 2023-06-17 28155.737704917978
79 2023-06-18 28196.721311475354
80 2023-06-19 28237.70491803273
81 2023-06-20 28278.688524590107
82 2023-06-21 28319.672131147483
83 2023-06-22 28360.65573770486
84 2023-06-23 28401.639344262236
85 2023-06-24 28442.622950819612
86 2023-06-25 28483.60655737699
87 2023-06-26 28524.590163934365
88 2023-06-27 28565.57377049174
89 2023-06-28 28606.557377049117
90 2023-06-29 28647.540983606494
91 2023-06-30 28688.52459016387
92 2023-07-01 28729.508196721246
93 2023-07-02 28770.491803278623
94 2023-07-03 28811.475409836
95 2023-07-04 28852.459016393375
96 2023-07-05 28893.44262295075
97 2023-07-06 28934.426229508128
98 2023-07-07 28975.409836065504
99 2023-07-08 29016.39344262288
100 2023-07-09 29057.377049180257
101 2023-07-10 29098.360655737633
102 2023-07-11 29139.34426229501
103 2023-07-12 29180.327868852386
104 2023-07-13 29221.311475409762
105 2023-07-14 29262.29508196714
106 2023-07-15 29303.278688524515
107 2023-07-16 29344.26229508189
108 2023-07-17 29385.245901639268
109 2023-07-18 29426.229508196644
110 2023-07-19 29467.21311475402
111 2023-07-20 29508.196721311397
112 2023-07-21 29549.180327868773
113 2023-07-22 29590.16393442615
114 2023-07-23 29631.147540983526
115 2023-07-24 29672.131147540902
116 2023-07-25 29713.11475409828
117 2023-07-26 29754.098360655655
118 2023-07-27 29795.08196721303
119 2023-07-28 29836.065573770407
120 2023-07-29 29877.049180327784
121 2023-07-30 29918.03278688516
122 2023-07-31 29959.016393442536
123 2023-08-01 29999.999999999913
124 2023-08-02 30040.98360655729
125 2023-08-03 30081.967213114665
126 2023-08-04 30122.95081967204
127 2023-08-05 30163.934426229418
128 2023-08-06 30204.918032786794
129 2023-08-07 30245.90163934417
130 2023-08-08 30286.885245901547
131 2023-08-09 30327.868852458923
132 2023-08-10 30368.8524590163
133 2023-08-11 30409.836065573676
134 2023-08-12 30450.819672131052
135 2023-08-13 30491.80327868843
136 2023-08-14 30532.786885245805
137 2023-08-15 30573.77049180318
138 2023-08-16 30614.754098360558
139 2023-08-17 30655.737704917934
140 2023-08-18 30696.72131147531
141 2023-08-19 30737.704918032687
142 2023-08-20 30778.688524590063
143 2023-08-21 30819.67213114744
144 2023-08-22 30860.655737704816
145 2023-08-23 30901.639344262192
146 2023-08-24 30942.62295081957
147 2023-08-25 30983.606557376945
148 2023-08-26 31024.59016393432
149 2023-08-27 31065.573770491697
150 2023-08-28 31106.557377049074
151 2023-08-29 31147.54098360645
152 2023-08-30 31188.524590163826
153 2023-08-31 31229.508196721203
154 2023-09-01 31270.49180327858
155 2023-09-02 31311.475409835955
156 2023-09-03 31352.45901639333
157 2023-09-04 31393.442622950708
158 2023-09-05 31434.426229508084
159 2023-09-06 31475.40983606546
160 2023-09-07 31516.393442622837
161 2023-09-08 31557.377049180213
162 2023-09-09 31598.36065573759
163 2023-09-10 31639.344262294966
164 2023-09-11 31680.327868852342
165 2023-09-12 31721.31147540972
166 2023-09-13 31762.295081967095
167 2023-09-14 31803.27868852447
168 2023-09-15 31844.262295081848
169 2023-09-16 31885.245901639224
170 2023-09-17 31926.2295081966
171 2023-09-18 31967.213114753977
172 2023-09-19 32008.196721311353
173 2023-09-20 32049.18032786873
174 2023-09-21 32090.163934426106
175 2023-09-22 32131.147540983482
176 2023-09-23 32172.13114754086
177 2023-09-24 32213.114754098235
178 2023-09-25 32254.09836065561
179 2023-09-26 32295.081967212987
180 2023-09-27 32336.065573770364
181 2023-09-28 32377.04918032774
182 2023-09-29 32418.032786885116
183 2023-09-30 32459.016393442493
183
184 2023-10-01 32459.016393442493
185 2023-10-02 32418.032786885116
186 2023-10-03 32377.04918032774
187 2023-10-04 32336.065573770364
188 2023-10-05 32295.081967212987
189 2023-10-06 32254.09836065561
190 2023-10-07 32213.114754098235
191 2023-10-08 32172.13114754086
192 2023-10-09 32131.147540983482
193 2023-10-10 32090.163934426106
194 2023-10-11 32049.18032786873
195 2023-10-12 32008.196721311353
196 2023-10-13 31967.213114753977
197 2023-10-14 31926.2295081966
198 2023-10-15 31885.245901639224
199 2023-10-16 31844.262295081848
200 2023-10-17 31803.27868852447
201 2023-10-18 31762.295081967095
202 2023-10-19 31721.31147540972
203 2023-10-20 31680.327868852342
204 2023-10-21 31639.344262294966
205 2023-10-22 31598.36065573759
206 2023-10-23 31557.377049180213
207 2023-10-24 31516.393442622837
208 2023-10-25 31475.40983606546
209 2023-10-26 31434.426229508084
210 2023-10-27 31393.442622950708
211 2023-10-28 31352.45901639333
212 2023-10-29 31311.475409835955
213 2023-10-30 31270.49180327858
214 2023-10-31 31229.508196721203
215 2023-11-01 31188.524590163826
216 2023-11-02 31147.54098360645
217 2023-11-03 31106.557377049074
218 2023-11-04 31065.573770491697
219 2023-11-05 31024.59016393432
220 2023-11-06 30983.606557376945
221 2023-11-07 30942.62295081957
222 2023-11-08 30901.639344262192
223 2023-11-09 30860.655737704816
224 2023-11-10 30819.67213114744
225 2023-11-11 30778.688524590063
226 2023-11-12 30737.704918032687
227 2023-11-13 30696.72131147531
228 2023-11-14 30655.737704917934
229 2023-11-15 30614.754098360558
230 2023-11-16 30573.77049180318
231 2023-11-17 30532.786885245805
232 2023-11-18 30491.80327868843
233 2023-11-19 30450.819672131052
234 2023-11-20 30409.836065573676
235 2023-11-21 30368.8524590163
236 2023-11-22 30327.868852458923
237 2023-11-23 30286.885245901547
238 2023-11-24 30245.90163934417
239 2023-11-25 30204.918032786794
240 2023-11-26 30163.934426229418
241 2023-11-27 30122.95081967204
242 2023-11-28 30081.967213114665
243 2023-11-29 30040.98360655729
244 2023-11-30 29999.999999999913
245 2023-12-01 29959.016393442536
246 2023-12-02 29918.03278688516
247 2023-12-03 29877.049180327784
248 2023-12-04 29836.065573770407
249 2023-12-05 29795.08196721303
250 2023-12-06 29754.098360655655
251 2023-12-07 29713.11475409828
252 2023-12-08 29672.131147540902
253 2023-12-09 29631.147540983526
254 2023-12-10 29590.16393442615
255 2023-12-11 29549.180327868773
256 2023-12-12 29508.196721311397
257 2023-12-13 29467.21311475402
258 2023-12-14 29426.229508196644
259 2023-12-15 29385.245901639268
260 2023-12-16 29344.26229508189
261 2023-12-17 29303.278688524515
262 2023-12-18 29262.29508196714
263 2023-12-19 29221.311475409762
264 2023-12-20 29180.327868852386
265 2023-12-21 29139.34426229501
266 2023-12-22 29098.360655737633
267 2023-12-23 29057.377049180257
268 2023-12-24 29016.39344262288
269 2023-12-25 28975.409836065504
270 2023-12-26 28934.426229508128
271 2023-12-27 28893.44262295075
272 2023-12-28 28852.459016393375
273 2023-12-29 28811.475409836
274 2023-12-30 28770.491803278623
275 2023-12-31 28729.508196721246
276 2024-01-01 28688.52459016387
277 2024-01-02 28647.540983606494
278 2024-01-03 28606.557377049117
279 2024-01-04 28565.57377049174
280 2024-01-05 28524.590163934365
281 2024-01-06 28483.60655737699
282 2024-01-07 28442.622950819612
283 2024-01-08 28401.639344262236
284 2024-01-09 28360.65573770486
285 2024-01-10 28319.672131147483
286 2024-01-11 28278.688524590107
287 2024-01-12 28237.70491803273
288 2024-01-13 28196.721311475354
289 2024-01-14 28155.737704917978
290 2024-01-15 28114.7540983606
291 2024-01-16 28073.770491803225
292 2024-01-17 28032.78688524585
293 2024-01-18 27991.803278688472
294 2024-01-19 27950.819672131096
295 2024-01-20 27909.83606557372
296 2024-01-21 27868.852459016343
297 2024-01-22 27827.868852458967
298 2024-01-23 27786.88524590159
299 2024-01-24 27745.901639344214
300 2024-01-25 27704.918032786838
301 2024-01-26 27663.93442622946
302 2024-01-27 27622.950819672085
303 2024-01-28 27581.96721311471
304 2024-01-29 27540.983606557333
305 2024-01-30 27499.999999999956
306 2024-01-31 27459.01639344258
307 2024-02-01 27418.032786885204
308 2024-02-02 27377.049180327827
309 2024-02-03 27336.06557377045
310 2024-02-04 27295.081967213075
311 2024-02-05 27254.0983606557
312 2024-02-06 27213.114754098322
313 2024-02-07 27172.131147540946
314 2024-02-08 27131.14754098357
315 2024-02-09 27090.163934426193
316 2024-02-10 27049.180327868817
317 2024-02-11 27008.19672131144
318 2024-02-12 26967.213114754064
319 2024-02-13 26926.229508196688
320 2024-02-14 26885.24590163931
321 2024-02-15 26844.262295081935
322 2024-02-16 26803.27868852456
323 2024-02-17 26762.295081967182
324 2024-02-18 26721.311475409806
325 2024-02-19 26680.32786885243
326 2024-02-20 26639.344262295053
327 2024-02-21 26598.360655737677
328 2024-02-22 26557.3770491803
329 2024-02-23 26516.393442622924
330 2024-02-24 26475.409836065548
331 2024-02-25 26434.42622950817
332 2024-02-26 26393.442622950795
333 2024-02-27 26352.45901639342
334 2024-02-28 26311.475409836043
335 2024-02-29 26270.491803278666
336 2024-03-01 26229.50819672129
337 2024-03-02 26188.524590163914
338 2024-03-03 26147.540983606537
339 2024-03-04 26106.55737704916
340 2024-03-05 26065.573770491785
341 2024-03-06 26024.59016393441
342 2024-03-07 25983.606557377032
343 2024-03-08 25942.622950819656
344 2024-03-09 25901.63934426228
345 2024-03-10 25860.655737704903
346 2024-03-11 25819.672131147527
347 2024-03-12 25778.68852459015
348 2024-03-13 25737.704918032774
349 2024-03-14 25696.721311475398
350 2024-03-15 25655.73770491802
351 2024-03-16 25614.754098360645
352 2024-03-17 25573.77049180327
353 2024-03-18 25532.786885245892
354 2024-03-19 25491.803278688516
355 2024-03-20 25450.81967213114
356 2024-03-21 25409.836065573763
357 2024-03-22 25368.852459016387
358 2024-03-23 25327.86885245901
359 2024-03-24 25286.885245901634
360 2024-03-25 25245.901639344258
361 2024-03-26 25204.91803278688
362 2024-03-27 25163.934426229505
363 2024-03-28 25122.95081967213
364 2024-03-29 25081.967213114753
365 2024-03-30 25040.983606557376
366 2024-03-31 25000.0
```