モンテカルロシミュレーションによる株価予測に関する研究ノート
モンテカルロシミュレーションによる株価予測に関する研究ノート
1. はじめに
金融工学の分野において、株価の将来予測はポートフォリオ最適化やリスク管理に不可欠である。本研究ノートでは、モンテカルロシミュレーションを用いて株価の確率的挙動を評価する方法について、数式的枠組みを交えて整理する。
2. データ取得
株価データは yfinance
ライブラリを用いて取得する:
$$
P_t = \text{yf.download}(\text{ticker}, t_0, t_1)
$$
ここで、 $P_t$ は時刻 $t$ における株価、$t_0, t_1$ は取得期間である。
3. リターンと統計量
株価リターンは以下のように定義される:
$$
R_t = \ln \frac{P_t}{P_{t-1}}
$$
この系列に基づき、次の統計量を計算する:
- 期待リターン(年率換算):
$$
\mu = \mathbb{E}[R_t] \times 252
$$
- ボラティリティ(年率換算):
$$
\sigma = \sqrt{\mathrm{Var}(R_t)} \times \sqrt{252}
$$
ここで、252は1年間の取引日数である。
4. モンテカルロシミュレーション
株価は幾何ブラウン運動 (Geometric Brownian Motion, GBM) に従うと仮定する:
$$
dS_t = \mu S_t dt + \sigma S_t dW_t
$$
離散化すると:
$$
S_{t+\Delta t} = S_t \exp \left( \left(\mu - \frac{1}{2}\sigma^2\right)\Delta t + \sigma \sqrt{\Delta t} Z \right)
$$
ここで、$Z \sim \mathcal{N}(0,1)$ は標準正規分布に従う乱数である。
シミュレーションの設定:
- 期間: $\Delta t = 0.25/12 \approx 0.0208$ (約1週間)
- 試行回数: $N = 10000$
5. 結果
最終日の価格分布を得ることで、次のような指標を算出できる:
- 平均価格:
$$
\overline{S_T} = \frac{1}{N}\sum_{i=1}^N S_T^{(i)}
$$
- 標準偏差:
$$
\mathrm{Std}(S_T) = \sqrt{\frac{1}{N}\sum_{i=1}^N (S_T^{(i)} - \overline{S_T})^2}
$$
ヒストグラムにより、価格分布の広がりとリスクの程度を可視化する。
6. 考察
モンテカルロシミュレーションにより、株価の「確率的な未来」を描くことができる。特に、平均値と標準偏差は将来価格の中心傾向とリスクの大きさを示す。実務的には、VaR(Value at Risk)やCVaR(Conditional VaR)といったリスク指標へと拡張可能である。
7. 結論
本研究ノートでは、モンテカルロ法を用いた株価予測の基本枠組みを示した。GBMモデルの単純さにもかかわらず、短期的リスク評価に有効であることが確認された。今後の研究課題として、ジャンプ拡散モデルや確率ボラティリティモデルへの拡張が挙げられる。
【Python実践】Yahoo Finance × モンテカルロシミュレーションで株価シナリオ分析
1. はじめに
株式投資において「将来の株価がどうなるか」を予測するのは非常に難しいテーマです。しかし、統計的な手法を使えば 株価の将来分布をシミュレーションし、リスクとリターンの幅を可視化 することができます。
今回の記事では、以下をPythonで実装していきます。
Yahoo Financeから株価データを取得
複数銘柄の終値を整理
モンテカルロシミュレーションで将来の株価を予測
分布を可視化し、リスク・リターンを分析
2. 株価データを取得する関数
まず、yfinance を使って株価データを取得する関数を定義します。
def get_stock_yf(stock, start, end):
df = yf.download(tickers=stock, start=start, end=end)
return df
引数
stock: ティッカーシンボル(例: "TSLA", "AMZN")
start, end: 取得期間
これで、任意の銘柄の株価データを簡単に取得できます。
3. 複数銘柄のデータを整理
次に、複数銘柄を辞書に登録し、一括で株価データを取得して 終値のデータフレーム を作成します。
stock_dict = {
'APP':'APP',
'SOFI':'SOFI',
'JMIA':'JMIA',
'PLTR':'PLTR',
'TSLA':'TSLA',
'AMZN':'AMZN',
'HIMS':'HIMS'
}
start = '2025-06-01'
end = '2025-08-24'
series_close = pd.DataFrame()
for name, stock in stock_dict.items():
df = pd.DataFrame(get_stock_yf(stock, start, end))
series_close[name] = df['Close']
series_close
このコードにより、各銘柄の「終値」だけをまとめたテーブルが完成します。
分析したい銘柄を選んで、直近の終値を取り出すことができます。
name = "JMIA"
last_ = series_close[name]
last_[-1]
ここで last_[-1] は選んだ銘柄の「直近の株価」です。
4. モンテカルロシミュレーションの準備
次に、株価シナリオを確率的に生成する モンテカルロシミュレーション を行います。
def monte_carlo_stock_price_with_data(
past_prices: pd.Series, # 過去の株価データ (Pandas Series)
time_horizon: float, # シミュレーション期間 (年)
num_simulations: int # シミュレーション回数
):
"""
過去データからモンテカルロシミュレーションを行い、将来の株価を予測します。
Args:
past_prices: 過去の株価データ (Pandas Series, indexが日付であること).
time_horizon: シミュレーション期間 (年).
num_simulations: シミュレーション回数.
Returns:
numpy.ndarray: 各シミュレーションにおける各時点の株価の配列 (num_simulations x (number of time steps + 1)).
"""
# 過去データからリターンとボラティリティを計算
returns = np.log(past_prices / past_prices.shift(1))
mu = returns.mean() * 252 # 年率換算 (252営業日)
sigma = returns.std() * np.sqrt(252) # 年率換算
# 現在の株価
current_price = past_prices.iloc[-1] # 最後の株価を使用
dt = 1 / 252 # 1日の期間 (営業日ベース)
num_steps = int(time_horizon / dt)
prices = np.zeros((num_simulations, num_steps + 1))
prices[:, 0] = current_price
for i in range(num_simulations):
for t in range(1, num_steps + 1):
z = np.random.normal(0, 1) # 標準正規分布に従う乱数
prices[i, t] = prices[i, t - 1] * np.exp((mu - 0.5 * sigma**2) * dt + sigma * np.sqrt(dt) * z)
return prices,mu,sigma,returns
time_horizon = 0.25/12 # 1週間 (年換算で約0.25か月)
num_simulations = 10000 # シミュレーション回数
simulated_prices, mu, sigma, returns = monte_carlo_stock_price_with_data(last_, time_horizon, num_simulations)
returns
mu: 年率換算リターン(平均的な上昇率)
sigma: 年率換算ボラティリティ(値動きの大きさ)
returns: 日次リターンの系列
simulated_prices: シミュレーションで生成された株価パス
5. シナリオ結果の分析と可視化
最後に、シミュレーション結果を統計的に評価します。
final_prices = simulated_prices[:, -1]
print(f"年率実績リターン: {mu:.2f}")
print(f"年率ボラティリティ: {sigma:.2f}")
print(f"最終日価格の平均: {np.mean(final_prices):.2f}")
print(f"最終日価格の標準偏差: {np.std(final_prices):.2f}")
import matplotlib.pyplot as plt
plt.hist(final_prices, bins=50)
plt.xlabel(f"価格: {time_horizon*252:.2f}d後")
plt.ylabel("頻度")
plt.title("モンテカルロシミュレーションによる:$"+name)
plt.show()
ここで分かること:
最終価格の平均 → 期待される株価水準
標準偏差 → 株価がどれくらい散らばるか(リスク)
ヒストグラム → 株価がどの価格帯に落ち着く可能性が高いか
6. まとめ
今回のコードでは、
-
Yahoo Financeから株価データを取得
-
複数銘柄の終値を比較・抽出
-
モンテカルロ法で株価シナリオを生成
-
リスクとリターンを可視化
という一連の分析を行いました。
この方法を使うと、投資判断の前に 「どれくらい上がる可能性があるか」「どれくらい下がるリスクがあるか」 を数字で把握できます。
今後はこれを発展させて:
期間を「1年」「半年」などに拡大
time_horizon = 12/12 #1年
time_horizon = 6/12 #半年
time_horizon = 1/12 #ひと月
など
複数銘柄のシナリオを比較
具体例
$JMIA
年率実績リターン: 3.87
年率ボラティリティ: 0.91
最終日価格の平均: 8.51
最終日価格の標準偏差: 1.10
$SOFI
年率実績リターン: 2.67
年率ボラティリティ: 0.49
最終日価格の平均: 26.39
最終日価格の標準偏差: 1.80
$HIMS
年率実績リターン: -1.07
年率ボラティリティ: 1.18
最終日価格の平均: 43.51
最終日価格の標準偏差: 7.29
$PLTR
年率実績リターン: 0.81
年率ボラティリティ: 0.52
最終日価格の平均: 161.12
最終日価格の標準偏差: 11.73
$APP
年率実績リターン: 0.42
年率ボラティリティ: 0.58
最終日価格の平均: 445.16
最終日価格の標準偏差: 36.53
$TSLA
年率実績リターン: -0.03
年率ボラティリティ: 0.59
最終日価格の平均: 339.95
最終日価格の標準偏差: 28.62
$AMZN
年率実績リターン: 0.45
年率ボラティリティ: 0.29
最終日価格の平均: 230.95
最終日価格の標準偏差: 9.27