7.1.14
配当再投資で総リターンをシミュレーションする
まとめ- 配当を再投資するシナリオと現金保持するシナリオを比較し、複利効果を定量的に確認する。
- pandasで月次の配当再投資ループを実装し、ポートフォリオの評価額推移をシミュレーションする。
- CAGR・最大ドローダウンなどの指標で、両シナリオのリスク・リターンを評価する。
直感
#
配当を現金のまま受け取る場合と、すぐに再投資する場合では長期の総リターンに大きな差が生まれます。再投資では配当で追加の株式を購入し、その株式からもさらに配当が得られるため、複利効果が働きます。この差は投資期間が長いほど大きくなり、10年以上の長期投資では総リターンの数十%を配当再投資が占めることも珍しくありません。
詳細な解説
#
擬似データの生成
#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pathlib import Path
np.random.seed(21)
plt.style.use("scripts/k_dm.mplstyle")
dates = pd.date_range("2015-01-01", periods=9 * 12, freq="M")
price = 100 * np.exp(np.cumsum(np.random.normal(0.005, 0.04, len(dates))))
dividend_yield = np.random.uniform(0.015, 0.025, len(dates)) # 年率1.5〜2.5%
frame = pd.DataFrame({"price": price, "dividend_yield": dividend_yield}, index=dates)
frame["dividend_cash"] = frame["price"] * frame["dividend_yield"] / 12
|
シナリオ1: 配当を現金のまま保持
#
配当は受け取るが再投資せず、株式1株 + 累積配当金で評価します。
1
2
| cash_hold = frame["dividend_cash"].cumsum()
total_value_cash = frame["price"] + cash_hold
|
シナリオ2: 配当を即座に再投資
#
配当で追加の株式を購入し、保有株数を増やします。
1
2
3
4
5
6
7
8
9
10
11
12
| shares = 1.0
cash = 0.0
portfolio_value = []
for price, dividend in zip(frame["price"], frame["dividend_cash"]):
cash += dividend
additional_shares = cash / price
shares += additional_shares
cash = 0.0
portfolio_value.append(shares * price)
total_value_reinvest = pd.Series(portfolio_value, index=frame.index)
|
結果を比較
#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| comparison = pd.DataFrame(
{
"現金保持": total_value_cash,
"再投資": total_value_reinvest,
}
)
fig, ax = plt.subplots(figsize=(9, 4.2))
comparison.plot(ax=ax)
ax.set_title("配当再投資シミュレーション(擬似データ)")
ax.set_ylabel("評価額(基準=100)")
ax.grid(alpha=0.3)
output = Path("static/images/finance/main/dividend_reinvestment.svg")
output.parent.mkdir(parents=True, exist_ok=True)
fig.tight_layout()
fig.savefig(output)
|

再投資による追加リターンの内訳
#
再投資がどの程度のリターン上乗せになったかを分離して確認します。
1
2
3
4
5
6
7
| final_cash = total_value_cash.iloc[-1]
final_reinvest = total_value_reinvest.iloc[-1]
reinvest_bonus = final_reinvest - final_cash
print(f"現金保持の最終評価額: {final_cash:.1f}")
print(f"再投資の最終評価額: {final_reinvest:.1f}")
print(f"再投資による上乗せ: {reinvest_bonus:.1f} ({reinvest_bonus/final_cash*100:.1f}%)")
|
CAGR(年平均成長率)の比較
#
長期投資の成果を比較するにはCAGR(Compound Annual Growth Rate)が有効です。
1
2
3
4
5
6
7
8
| years = len(dates) / 12
cagr_cash = (total_value_cash.iloc[-1] / 100) ** (1 / years) - 1
cagr_reinvest = (total_value_reinvest.iloc[-1] / 100) ** (1 / years) - 1
print(f"CAGR(現金保持): {cagr_cash:.2%}")
print(f"CAGR(再投資): {cagr_reinvest:.2%}")
print(f"差分: {cagr_reinvest - cagr_cash:.2%}")
|
最大ドローダウンの比較
#
再投資シナリオでは保有株数が増えるため、下落局面での評価額の減少幅も大きくなります。リスク面も確認します。
1
2
3
4
5
6
7
8
9
10
| def max_drawdown(series: pd.Series) -> float:
cummax = series.cummax()
drawdown = (series - cummax) / cummax
return drawdown.min()
mdd_cash = max_drawdown(total_value_cash)
mdd_reinvest = max_drawdown(total_value_reinvest)
print(f"最大ドローダウン(現金保持): {mdd_cash:.2%}")
print(f"最大ドローダウン(再投資): {mdd_reinvest:.2%}")
|
実務に向けて
#
- 実際のデータを利用する際は、配当落ち日・支払日を考慮して再投資のタイミングを合わせます。
- 海外株の場合は源泉徴収税や為替影響を考慮する必要があります。税引後配当を用意し、合計ネットリターンを比較するとより現実的です。
- ポートフォリオ全体では、銘柄ごとの配当再投資をまとめて日次で行うか、一定金額が貯まった段階でまとめて再投資するなど、運用ルールを明示して検証しましょう。
- DRIPプラン(配当再投資プラン)を提供する証券会社では手数料無料で自動再投資が可能なため、実装コストの違いも考慮に入れます。