import streamlit as st import pandas as pd import numpy as np import statsmodels.api as sm import matplotlib.pyplot as plt # データ生成関数 def generate_data(days=252): np.random.seed(0) dates = pd.date_range(start='2023-01-01', periods=days, freq='B') initial_values = { 'stock_index': 1000, 'swap_rate': 0.25, 'fx_rate': 110, 'credit_spread': 10 } daily_volatility = { 'stock_index': 0.01, 'swap_rate': 0.0001, 'fx_rate': 0.001, 'credit_spread': 0.1 } data = pd.DataFrame(index=dates) for key, value in initial_values.items(): daily_changes = np.random.normal(loc=0, scale=daily_volatility[key], size=days) data[key] = value * (1 + np.cumsum(daily_changes)) return data # データ生成 data = generate_data() # Streamlit UI設定 st.title("インパルス応答とモンテカルロシミュレーション") # 変数選択 variable = st.selectbox("変数を選択してください", data.columns) # VARモデルのフィッティング model = sm.tsa.VAR(data) results = model.fit(maxlags=5) # 誤差共分散行列に小さい正の定数を追加して正定値にする sigma = results.sigma_u epsilon = 1e-10 # 小さい正の定数 sigma += epsilon * np.eye(sigma.shape[0]) # インパルス応答の生成と表示 irf = results.irf(10) st.write(f"インパルス応答関数: {variable}") fig = irf.plot(orth=True, impulse=variable) st.pyplot(fig) # モンテカルロシミュレーション simulations = [] num_simulations = 100 for _ in range(num_simulations): simulated_data = results.simulate_var(steps=252) simulations.append(simulated_data) # シミュレーション結果の平均と信頼区間の計算 simulations = np.array(simulations) mean_simulation = np.mean(simulations, axis=0) std_simulation = np.std(simulations, axis=0) # グラフの作成と表示 st.write("モンテカルロシミュレーション結果") fig, ax = plt.subplots(figsize=(12, 8)) for i, column in enumerate(data.columns): ax.plot(data.index, mean_simulation[:, i], label=f'Mean Simulation - {column}') ax.fill_between(data.index, mean_simulation[:, i] - 1.96*std_simulation[:, i], mean_simulation[:, i] + 1.96*std_simulation[:, i], alpha=0.2) ax.legend() st.pyplot(fig)