【ドルコスト平均法】外貨積立をシミュレーションしてみる🎵

昨日、[【ドルコスト平均法】オルカンなのかSP500なのか、NVIDIAはたまた国内株なのか、。。。よりリアルにNISAのゲインを追求する🎵](https://qiita.com/MuAuan/items/452a21e95c8a7e51a97e)を書いたが、外貨積立もドルコスト平均法で積立てる仕組みがあるので、今回は、それを同様にシミュレーションしてみる。
為替データは、以下の参考のとおりであるが、一部仕様が変わり、参考②のように変更が必要であった。
【参考】
①[【シストレ入門】FXと株価時系列のシミュレータ作って遊んでみた♬](https://qiita.com/MuAuan/items/4fede457efcd1fcd908c)
②[pandas-datareaderでyahooファイナンスのデータを取得する方法](https://knowledge-bridge.info/technology/statistics/3654/)
## コード変更
### 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
```
fxデータの取得検証は、以下のとおりで、動いたので昨日のコードと合わせるとfxデータでのドルコスト平均法のシミュレーションのプログラムができる。

```get_fxdata.py
import pandas_datareader.data as DataReader
 
yf.pdr_override() #これが必要になった；
# 参考; https://knowledge-bridge.info/technology/statistics/3654/

start = dt.date(2019,1,1)
end = dt.date(2021,3,18)

stock0= 'GBPJPY=X'
df=DataReader.get_data_yahoo("{}".format(stock0),start,end) 
df
```
したがって、取得関数を以下のように定義する。

```getfx.py
def get_fx_yf(stock,start,end):
    df = DataReader.get_data_yahoo("{}".format(stock0),start,end) 
    return df
```
### getfx.pyを利用
```getfx_.py
start = '2004-04-01'
end = '2024-03-31'
stock = 'GBPJPY=X'
df = pd.DataFrame(get_fx_yf(stock, start, end))
df['Close']
```
### 取引日定義
```workdate.py
df['date'] = df.index
```
### 投資日定義
昨日のコードと同様に投資日をdf_dateに設定する。
※今回は月一投資とする。実際は週次や日次もできそうである。

```deal.py
df_date = pd.DataFrame()
d_series = df['date']
target_dates = '20'
date_list = []
for k in ('04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24'):
    target_date = target_dates + k +'-'

    for j in ('01','02','03','04','05','06','07','08','09','10','11','12'):
        target_date_ = target_date + j
        for i in ("01","02","03","04","05","06","07"):
            target_date2 = target_date_ + '-' + i
            exists = (d_series == target_date2).any()
            #print(target_date2, exists)
            if(exists == True):
                date_list.append(target_date2)
                break
df_date = date_list
```
### 投資する
```buy_fx.py
yosan0 = 33000
def yosan_make(market, price_ave):
    yosan = yosan0 #毎月投資額　33,000円 price_aveで変更可
    return yosan

pd_stock = pd.DataFrame()

def market_history(df):
    i_list = []
    cost_list = []
    kutisu_list = []
    kutisu_sum_list = []
    kutisu_sum = 0
    cost_sum_list = []
    cost_sum = 0
    price_sum = 0
    price = 0
    mean_price_list = []
    heikin_cost_list = []
    price_list = []
    j = 0
    for i in df_date:
        price = df['Close'][i]
        price_list.append(price)
        
        i_list.append(i)
        price_sum += df['Close'][i]
        price_ave = price_sum/(j+1)
        mean_price_list.append(price_ave)
        yosan = yosan_make(df['Close'][i], price_ave)
        cost_list.append(yosan)
        cost_sum += yosan
        cost_sum_list.append(cost_sum)
        kutisu = yosan/df['Close'][i]
        kutisu_list.append(kutisu)
        kutisu_sum +=kutisu
        kutisu_sum_list.append(kutisu_sum)
        heikin_cost_list.append(cost_sum/kutisu_sum)
        j +=1

    pd_stock['date'] = i_list
    pd_stock['price'] = price_list 
    pd_stock['mean_price'] = mean_price_list
    pd_stock['kutisu'] = kutisu_list #yosan/df['Close']
    pd_stock['cost'] = cost_list
    pd_stock['cost_sum'] = cost_sum_list
    pd_stock['kutisu_sum'] = kutisu_sum_list
    pd_stock['jika'] = pd_stock['price']*pd_stock['kutisu_sum']
    pd_stock['heikin_cost'] = heikin_cost_list
    return pd_stock

pd_stock = market_history(df)
pd_stock
```
出力
```pd_stock
	date	price	mean_price	kutisu	cost	cost_sum	kutisu_sum	jika	heikin_cost
0	2004-04-01	192.559998	192.559998	171.375158	33000	33000	171.375158	3.300000e+04	192.559998
1	2004-05-03	195.070007	193.815002	169.170035	33000	66000	340.545193	6.643015e+04	193.806876
2	2004-06-01	203.199997	196.943334	162.401577	33000	99000	502.946770	1.021988e+05	196.839916
3	2004-07-01	197.380005	197.052502	167.190187	33000	132000	670.136958	1.322716e+05	196.974661
4	2004-08-02	202.130005	198.068002	163.261264	33000	165000	833.398221	1.684548e+05	197.984584
...	...	...	...	...	...	...	...	...	...
235	2023-11-01	183.835007	164.324162	179.508792	33000	7788000	48994.709143	9.006943e+06	158.955939
236	2023-12-01	186.927002	164.419532	176.539503	33000	7821000	49171.248645	9.191434e+06	159.056364
237	2024-01-01	179.388000	164.482425	183.958793	33000	7854000	49355.207438	8.853732e+06	159.132144
238	2024-02-01	186.345993	164.573905	177.089936	33000	7887000	49532.297374	9.230145e+06	159.229441
239	2024-03-01	189.483002	164.677692	174.158102	33000	7920000	49706.455477	9.418528e+06	159.335441
240 rows × 9 columns
```
### 
```describe().py
pd_stock['price'].describe()
```

```price.describ().py
count    240.000000
mean     164.677692
std       31.211474
min      119.519997
25%      140.799248
50%      154.909500
75%      186.554245
max      246.610001
Name: price, dtype: float64
```

```heikin_cost.py
pd_stock['heikin_cost'].describe()
```

```heikin_cost_describe().py
count    240.000000
mean     175.874956
std       18.400353
min      158.127092
25%      161.532042
50%      165.438397
75%      197.028935
max      211.888245
Name: heikin_cost, dtype: float64
```

```投資額.py
pd_stock['cost'].describe()
```

```cost_describe().py
count      240.0
mean     33000.0
std          0.0
min      33000.0
25%      33000.0
50%      33000.0
75%      33000.0
max      33000.0
Name: cost, dtype: float64
```
### グラフ描画
```draw.py
fig, ax = plt.subplots(4,1)
ax[0].plot(pd_stock['price'])
ax[0].set_title('price')
ax[1].plot(pd_stock['kutisu'])
ax[1].set_title('kutisu')
ax[2].plot(pd_stock['price'])
ax[2].plot(pd_stock['mean_price'])
ax[2].set_title('mean_price')
ax[2].plot(pd_stock['heikin_cost'])
ax[3].plot(pd_stock['jika'])
ax[3].plot(pd_stock['cost_sum'])

plt.pause(1)
```

### GBP/JPY

![gbp_dolcost.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/f23cb38e-7d65-4b46-bd8e-2393020033ea.png)
投資総額　口数　総額　利益
7920000 49706 9418528 1498528
## ドル／円
![USDJPN_real.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/4f173b2e-1b9e-fc6a-73eb-7da9eb2fbba3.png)
投資総額　口数　総額　利益
7887000 74739 11217935 3330935
## ユーロ／円
![EURJPY_real.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/dd779f9f-2100-7e6f-afaa-eae17af6cece.png)
投資総額　口数　総額　利益
7887000 60559 9820745 1933745
### ZAR/JPY
![ZARJPY_real.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/06c30d33-8f66-0d75-71e2-a3da1297bc7d.png)
投資総額　口数　総額　利益
7920000 814953 6364214 -1555786
## まとめ
・一応、ドルコスト平均法で積立外貨預金を実施した場合のシミュレーションを実施した
・実際には、得られる利益には為替手数料とスワップが大きく、この計算ではおおよその予測しかできていない
・次回は、為替手数料とスワップを適当に入れて計算してみようと思う
・感覚的に価格変動がそこまで大きくないので、株に比べて為替でのドルコスト平均法のメリットは小さいような気がする