Pythonで特定口座にあるオルカンを新NISAに買い換えるタイミングを分析してみる

# 目的
現在特定口座で積み立てているオールカントリー投資信託を新NISA口座に移し替えたい。実際移し替えることはできないので、投資信託を売って、買うことになる。積み立て枠は毎月10万売って10万買えば良い。では成長枠の240万はいつ売って、いつ買えば良いのか？
「セルインメイ（5月に売ってどこかに行け、セント・レジャー・デーまで戻ってくるな）」の格言通り5月に売れば良い？

# MSCIオールカントリーワールドインデックスの一年の値動きを分析してみる

MSCIオールカントリーワールドインデックス（MSCI ACWI）の一年の値動きをYahoo Financeから取得したデータを元に分析してみることにする。
2008年からのデータになっているのはYahoo Financeに2008年より前のデータがないからだ。ちなみに2008年というとリーマンショックの年で、ここから各国中央銀行はじゃぶじゃぶ金融緩和を始め世界株は上がり調子である。アテになるかどうかはわからない。

## 実際のコード

### 1月を基準とした各月の割合を年ごとにプロットしてみる
```python
import yfinance as yf

# MSCIオールカントリーのティッカーシンボルを設定
ticker_symbol = "ACWI"

# 2008年から2023年までのデータを取得
data = yf.download(ticker_symbol, start="2008-01-01", end="2023-12-31")

# 月毎の平均価格を計算
monthly_data = data['Close'].resample('M').mean()

# 年と月の列を作成するために、インデックスを保持
monthly_data = monthly_data.reset_index()

# 年と月のデータを抽出
monthly_data['Year'] = monthly_data['Date'].dt.year
monthly_data['Month'] = monthly_data['Date'].dt.month

# データを年ごとにピボット
pivot_data = monthly_data.pivot_table(index='Year', columns='Month', values='Close')

# 1月のデータで割る（1月のデータを基準とした割合にする）
price_ratios = pivot_data.divide(pivot_data[1], axis=0)

import matplotlib.pyplot as plt

plt.figure(figsize=(10, 6))
# 各年のデータをプロット
for year in price_ratios.index:
    plt.plot(price_ratios.columns, price_ratios.loc[year], label=str(year))

plt.xlabel('Month')
plt.ylabel('Price Ratio to January')
plt.title('Monthly Price Ratios Relative to January for Each Year')
plt.xticks(range(1, 13))  # 月を1から12まで表示
plt.legend()
plt.grid(True)
plt.show()
```
さて、結果はこのようになった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31763/d7668421-e584-b13d-cb12-f7f4ac0988c7.png)

うん。よくわからない。

### 各月の平均をとってみる

```python
# 各月の平均を出す
monthly_average_ratios = price_ratios.mean()

# monthly_average_ratiosをプロット
plt.figure(figsize=(10, 6))
plt.plot(monthly_average_ratios.index, monthly_average_ratios.values, marker='o')

plt.xlabel('Month')
plt.ylabel('Average Price Ratio')
plt.title('Average Monthly Price Ratios Relative to January')
plt.xticks(range(1, 13))  # 月を1から12まで表示
plt.grid(True)
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31763/907f8eed-5182-7021-68d6-7a8c8ea34c5a.png)

なるほど。12月に売って3月に買うのが良さそうだ。

### 一応中央値も見ておこう

```python
# 各月の中央値を取得
monthly_median_ratios = price_ratios.median()

# monthly_median_ratiosをプロット
plt.figure(figsize=(10, 6))
plt.plot(monthly_median_ratios.index, monthly_median_ratios.values, marker='o')

plt.xlabel('Month')
plt.ylabel('Median Price Ratio')
plt.title('Median Monthly Price Ratios Relative to January')
plt.xticks(range(1, 13))  # 月を1から12まで表示
plt.grid(True)
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31763/7839f598-12b8-c7eb-375e-23946ca718e5.png)

1月に買って12月に売れば良いようだ。しかしこの結果はドルベースなので、為替は勘案されていない。

### ドル円レートを掛け合わせてみる

```python
import yfinance as yf
import pandas as pd

# MSCIオールカントリーとUSD/JPYのティッカーシンボルを設定
ticker_symbol_stock = "ACWI"
ticker_symbol_forex = "USDJPY=X"

# 株価データの取得
stock_data = yf.download(ticker_symbol_stock, start="2008-01-01", end="2023-12-31")

# 為替レートデータの取得
forex_data = yf.download(ticker_symbol_forex, start="2008-01-01", end="2023-12-31")

# 為替レートの月毎平均を計算
monthly_forex_data = forex_data['Close'].resample('M').mean()

# 株価データの月毎平均を計算
monthly_stock_data = stock_data['Close'].resample('M').mean()

# データをマージ
merged_data = pd.merge(monthly_stock_data, monthly_forex_data, left_index=True, right_index=True, how='inner')

# 株価に為替レートを掛け合わせ
merged_data['Adjusted_Close'] = merged_data['Close_x'] * merged_data['Close_y']

# 年と月の列を作成するために、インデックスを保持
merged_data = merged_data.reset_index()

# 年と月のデータを抽出
merged_data['Year'] = merged_data['Date'].dt.year
merged_data['Month'] = merged_data['Date'].dt.month

# データを年ごとにピボット
pivot_data = merged_data.pivot_table(index='Year', columns='Month', values='Adjusted_Close')

# 1月のデータで割る（1月のデータを基準とした割合にする）
price_ratios = pivot_data.divide(pivot_data[1], axis=0)

import matplotlib.pyplot as plt

plt.figure(figsize=(10, 6))
# 各年のデータをプロット
for year in price_ratios.index:
    plt.plot(price_ratios.columns, price_ratios.loc[year], label=str(year))

plt.xlabel('Month')
plt.ylabel('Price Ratio to January')
plt.title('Monthly Price Ratios Relative to January for Each Year')
plt.xticks(range(1, 13))  # 月を1から12まで表示
plt.legend()
plt.grid(True)
plt.show()
```

結果は以下のような感じだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31763/0a4a0393-f2da-ae7e-d697-a8f3dd126ad6.png)

### 各月の平均を取ろう

```python
monthly_average_ratios = price_ratios.mean()
# monthly_average_ratiosをプロット
plt.figure(figsize=(10, 6))
plt.plot(monthly_average_ratios.index, monthly_average_ratios.values, marker='o')

plt.xlabel('Month')
plt.ylabel('Average Price Ratio')
plt.title('Average Monthly Price Ratios Relative to January')
plt.xticks(range(1, 13))  # 月を1から12まで表示
plt.grid(True)
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31763/63c04f58-7323-5248-ca24-8225e11c8e9d.png)

似たような感じですね。1月に買って、12月に売りましょう。

# 結論

1月か3月に買って、12月に売りましょう（240万円の余裕資金が必要だけど）。

# P.S

「セルインメイ（Sell in May ,and go away ,don’t comeback until St Leger day）」は正しいですね。確かに5月から9月（セント・レジャー・デー）ぐらいまではほとんど動かない。一旦利確して遊んでた方が良いですね。