最適な投資戦略
概要
- S&P 500, NIKKEI 225, TOPIX, AWCI, NASDAQ 100などがあるが、どれが最適なのか?をシミュレーションを行いつつ検討
- 子供の教育資金を積み立てるための投資戦略を検討
- データはYahoo Finance(yfinance)を使用
株価のシミュレーション方法
- 幾何ブラウン運動
- 確率微分方程式を用いて株価のシミュレーションを行う方法
- ブートストラップ法
- 過去の株価データを用いて、将来の株価をシミュレーションする方法
- 簡単に計算できるが、過去のデータに依存する
幾何ブラウン運動の式
\[dS = \mu S dt + \sigma S dW\]- $S$: 株価
- $\mu$: 平均収益率
- $\sigma$: ボラティリティ
- $dW$: ウィーナプロセス
期待値とボラティリティの計算方法
- 対数収益率を用いて、期待値とボラティリティを計算する
for (ticker,), sub in df.groupby(by=["ticker"]):
sub = sub.sort_values(by=["date"]) # より明確な代入を使用
returns = np.log(sub["Close"].pct_change() + 1)
mu = returns.mean()
sigma = returns.std()
各指標の期待値とボラティリティとシャープレシオ
ticker | mu | sigma | sharpe ratio |
---|---|---|---|
TQQQ | 0.001247 | 0.047948 | 0.026005 |
DIA | 0.000399 | 0.013097 | 0.030498 |
ACWI | 0.000395 | 0.012654 | 0.031251 |
VOO | 0.000542 | 0.013430 | 0.040361 |
1321.T | 0.000569 | 0.012184 | 0.046704 |
1306.T | 0.000511 | 0.010925 | 0.046809 |
QQQ | 0.000763 | 0.016011 | 0.047650 |
FNGS | 0.001171 | 0.021010 | 0.055729 |
ブートストラップ法でのシミュレーション
- 2019-02-25 ~ 2024-02-24の5年間の株価データを用いて、ブートストラップ法でのシミュレーションを行う
- データはYahoo Financeから取得
plt.figure(figsize=(50, 30))
f, axs = plt.subplots(nrows=8, ncols=2, figsize=(30, 30))
for k, ((ticker,), sub) in enumerate(df.groupby(by=["ticker"])):
sub = sub.sort_values(by=["date"]) # より明確な代入を使用
returns = (sub["Close"].pct_change() + 1).fillna(1.0)
s = np.random.choice(returns, (5000, 240 * 10), replace=True)
rates = []
for i in range(len(s)):
cumulative_returns = 1
total_investment = 1
for r in s[i]:
cumulative_returns *= r
cumulative_returns += 1
total_investment += 1
rates.append(cumulative_returns / total_investment)
data = pd.DataFrame()
data["rate"] = pd.Series(rates)
ax0 = axs[k, 0]
sns.histplot(data=data, x="rate", kde=True, bins=np.arange(0, 20, 0.25), stat="probability", ax=ax0)
ax0.set(xlim=(0, 20), xticks=np.arange(0, 20, 0.25), title=ticker)
ax0.set_xticklabels(ax0.get_xticklabels(), rotation=90)
ax0.axvline(data["rate"].mean(), color='r', linestyle='--', linewidth=2)
ax0.axvline(data["rate"].median(), color='b', linestyle='--', linewidth=2)
ax1 = axs[k, 1]
sns.histplot(data=data, x="rate", kde=True, bins=np.arange(0, 20, 0.25), cumulative=True, stat="probability", ax=ax1)
ax1.set(xlim=(0, 20), xticks=np.arange(0, 20, 0.25), title=ticker + "(cumulative)")
ax1.set_xticklabels(ax1.get_xticklabels(), rotation=90)
plt.tight_layout()
plt.show()
結果
- 10年間のシミュレーション結果をプロット
- 期待値と中央値をプロット
結論
- 10年間のシミュレーション結果を見ると、最も期待値が高いのはTQQQであることがわかる
- しかし、中央値は低いところに位置し、最頻値も低い
- FNGSは期待値が高く、中央値も高いところに位置している
- また、最頻値も高く、下位5%になってもひどいことにならない