🎓 レベル:標準 | 重要度:A(必須)
📎 前提:ARCHとGARCHモデル | 関連:定常性と自己相関(ACF)・モデル選択と残差診断(残差のARCH効果)
要点(BLUF)
- ボラティリティクラスタリング=大きな変動の後には大きな変動が続く(凪の後は凪)。これが ARCH 効果の正体です(ARCHとGARCHモデル)。
- 指紋:リターン自体の ACF はほぼ0(平均は無相関)なのに、リターンの2乗(や絶対値)の ACF は有意に正——分散に自己相関がある。
Ljung-Box(2乗残差)やARCH-LM検定で判定します(定常性と自己相関 の ACF)。 - 予測:GARCH は分散を多期先予測でき、時変の予測区間 を作れます。点予測(≈0)だけでは不十分で、区間が時期で伸縮し、多期先では無条件分散へ収束します。
1. ボラティリティクラスタリングとは
金融リターンを眺めると、荒れる時期と凪の時期が固まって現れます。暴落の直後は連日大きく動き、落ち着けばしばらく穏やかが続く。これを ボラティリティクラスタリングと呼びます。GARCH(1,1) の漸化式
がまさにこれを生みます——大きなショック が来ると が上がり、 を通じて高ボラ状態が次々に持続する(ARCHとGARCHモデル)。重要なのは、この依存は「水準(平均)」ではなく「変動の大きさ(分散)」に現れること。だから普通の ACF(定常性と自己相関)をリターンに当てても見えず、リターンの2乗に当てて初めて指紋が浮かびます。
2. 指紋:リターンの ACF ≈ 0 vs リターン2乗の ACF は有意
リターン は、 が i.i.d. なのでそれ自体は無相関()。ところが2乗 は が過去に依存するぶん自己相関を持ちます。これが ARCH 効果を見つける鍵です。
- リターンの ACF:白色なら全ラグで信頼帯 内。
- リターン2乗の ACF:低ラグで有意に正なら分散に依存あり=ARCH 効果。
- 検定:
Ljung-Box(帰無=自己相関なし)を2乗系列に当てる、またはARCH-LM検定(帰無=ARCH 効果なし)。小さい 値で分散変動ありと判定。
コード①:リターン vs リターン2乗の ACF を数値で対比
真の GARCH(1,1)()の擬似リターンを作り、リターンの ACF とリターン2乗の ACF を並べ、Ljung-Box と ARCH-LM で ARCH 効果を判定します。
import numpy as np
from arch.univariate import ZeroMean, GARCH, Normal
from statsmodels.tsa.stattools import acf
from statsmodels.stats.diagnostic import acorr_ljungbox, het_arch
# 真の GARCH(1,1) リターンを生成(リターン自体は無相関だが分散が連動)
sim_model = ZeroMean()
sim_model.volatility = GARCH(p=1, q=1)
sim_model.distribution = Normal(seed=np.random.default_rng(7))
returns = sim_model.simulate([0.2, 0.10, 0.85], nobs=4000)["data"].values
n = len(returns)
band = 1.96 / np.sqrt(n) # ACFの95%有意帯(白色なら±この範囲)
acf_r = acf(returns, nlags=5, fft=True)
acf_r2 = acf(returns**2, nlags=5, fft=True)
print(f"95% band = +/-{band:.3f}")
print(f"{'lag':>4}{'ACF(r)':>10}{'ACF(r^2)':>12}")
for k in range(1, 6):
print(f"{k:>4}{acf_r[k]:>10.3f}{acf_r2[k]:>12.3f}")
# Ljung-Box(帰無=自己相関なし): リターン vs リターン2乗
lb_r = acorr_ljungbox(returns, lags=[10], return_df=True)["lb_pvalue"].iloc[0]
lb_r2 = acorr_ljungbox(returns**2, lags=[10], return_df=True)["lb_pvalue"].iloc[0]
print(f"Ljung-Box p returns = {lb_r:.3f} (large -> no autocorr)")
print(f"Ljung-Box p returns^2 = {lb_r2:.3e} (small -> autocorr in variance)")
# ARCH-LM 検定(帰無=ARCH効果なし)
lm_stat, lm_p, f_stat, f_p = het_arch(returns, nlags=10)
print(f"ARCH-LM stat = {lm_stat:.1f} p = {lm_p:.3e} -> ARCH effect present")
出力:
95% band = +/-0.031
lag ACF(r) ACF(r^2)
1 0.005 0.197
2 0.006 0.157
3 0.009 0.163
4 -0.015 0.144
5 -0.018 0.156
Ljung-Box p returns = 0.922 (large -> no autocorr)
Ljung-Box p returns^2 = 2.554e-197 (small -> autocorr in variance)
ARCH-LM stat = 410.0 p = 7.003e-82 -> ARCH effect present
出力の意味:リターンの ACF は全ラグで 帯の内側()=ほぼ無相関。一方リターン2乗の ACF は と帯を大きく超えて有意に正——分散に自己相関がある証拠です。Ljung-Box も、リターンでは (自己相関なしを棄却しない)に対し、2乗では (強く棄却)と対照的。ARCH-LM 検定も で「ARCH 効果あり」。**「平均は予測できないが分散は予測できる」**という GARCH の前提が、検定でも裏づきます。これは ARIMA の残差診断(モデル選択と残差診断)で「残差は白色なのに残差2乗に相関が残る」ときに GARCH を足す合図でもあります。
3. ボラティリティ予測と時変の予測区間
GARCH の予測対象は水準ではなく分散です。 期先の条件付き分散は、GARCH(1,1) なら漸化式を前向きに回して
と書けます(解析的)。持続性 なので、多期先では無条件分散 へ指数的に収束します。点予測(平均)は ≈0 のままでも、予測区間 は時期と先読みで伸縮する——ここが ARIMA の「区間は単調に広がる」(ARMA・ARIMAモデル)と決定的に違う点です。
flowchart LR
A["リターン r_t(平均≈0)"] --> B["GARCH(1,1) を推定"]
B --> C["条件付きボラ sigma_t を更新"]
C --> D["多期先の分散予測 sigma_{t+h}^2"]
D --> E["時変の予測区間 ±1.96 sigma_{t+h}"]
D --> F["h を増やすと無条件分散へ収束"]
コード②:時変区間とボラ予測(無条件分散へ収束)
GARCH(1,1) を推定し、(a) 時変の95%帯 がリターンを約95%覆うか(点予測=0だけでは不十分)、(b) 多期先の分散予測が無条件分散へ収束するか、を確かめます。図では帯が時期で伸縮します。
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib # 日本語ラベル用
from arch.univariate import ZeroMean, GARCH, Normal
from arch import arch_model
# 真の GARCH(1,1) リターンを生成
sim_model = ZeroMean()
sim_model.volatility = GARCH(p=1, q=1)
sim_model.distribution = Normal(seed=np.random.default_rng(7))
returns = sim_model.simulate([0.2, 0.10, 0.85], nobs=2000)["data"].values
# GARCH(1,1) を推定
fit = arch_model(returns, mean="Zero", vol="GARCH", p=1, q=1, dist="normal").fit(disp="off")
sigma = fit.conditional_volatility # 1期先ボラ sigma_t(時変)
uncond_var = fit.params["omega"] / (1 - fit.params["alpha[1]"] - fit.params["beta[1]"])
# (a) 時変の95%帯 ±1.96 sigma_t がリターンを約95%覆うか(点予測=0だけでは不十分)
lo, hi = -1.96 * sigma, 1.96 * sigma
cover = np.mean((returns > lo) & (returns < hi))
print(f"time-varying band width: min={2*1.96*sigma.min():.2f} max={2*1.96*sigma.max():.2f}")
print(f"95% band coverage of returns = {cover*100:.1f}%")
# (b) 多期先の分散予測(最終時点から): 無条件分散へ収束
fc = fit.forecast(horizon=100) # analytic(GARCHは多期先も解析的)
var_path = fc.variance.iloc[-1].values # h.1 ... h.100
for h in [1, 5, 20, 50, 100]:
print(f"h={h:>3} var forecast={var_path[h-1]:.3f} sigma={np.sqrt(var_path[h-1]):.3f}")
print(f"unconditional var (limit) = {uncond_var:.3f}")
# 図:直近400点のリターンに時変95%帯を重ねる(帯が時期で伸縮)
seg = slice(1600, 2000)
t = np.arange(1600, 2000)
plt.figure(figsize=(10, 4.5))
plt.plot(t, returns[seg], color="gray", lw=0.7, label="リターン r_t")
plt.fill_between(t, lo[seg], hi[seg], color="C0", alpha=0.25, label="時変95%帯 ±1.96σ_t")
plt.axhline(0, ls=":", color="k", lw=1, label="点予測 ≈ 0")
plt.xlabel("時点 t"); plt.ylabel("r_t"); plt.legend(loc="upper right")
plt.title("時変予測区間:点予測は0でも帯が時期で伸縮する")
plt.tight_layout(); plt.show()
出力:
time-varying band width: min=5.62 max=19.87
95% band coverage of returns = 94.9%
h= 1 var forecast=5.715 sigma=2.391
h= 5 var forecast=5.385 sigma=2.321
h= 20 var forecast=4.680 sigma=2.163
h= 50 var forecast=4.299 sigma=2.073
h=100 var forecast=4.234 sigma=2.058
unconditional var (limit) = 4.231
出力の意味:(a) 時変の95%帯の幅は最小 ・最大 と時期で3倍以上に伸縮し、リターンの を覆いました——名目95%とよく一致(較正済み)。点予測(橙の0線)だけでは「いま危険か穏やかか」が一切表せないのに対し、 の帯はそれを定量化します。(b) 多期先の分散予測は で (推定時点が高ボラ局面)から始まり、 で ——無条件分散 へ収束します。これは前ノートの「 が均衡点」の数値確認です(ARCHとGARCHモデル)。先読みが長いほど「いまの局面情報」が薄れ、長期平均の分散へ戻る——遠い将来のボラは結局「平均的な荒さ」に落ち着く、と読みます。
補足(VaR):金融実務ではこの を VaR(Value at Risk) に使います。正規を仮定すれば1日先の99% VaR は (保有額に対する損失の下側分位点)。GARCH で が時変なら、VaR も日々更新されます。深入りはしませんが、「時変ボラ → 時変リスク指標」という応用先がある、と押さえておけば十分です。
4. 数式の直観
- 2乗が分散の自己相関を映す鏡: なので、 は分散の「ノイズ込みの観測」。 が過去に依存すれば も自己相関を持つ——だから2乗の ACF が ARCH 効果を映す。実は GARCH(1,1) は が ARMA(1,1) に従う、と書き換えられます( が AR 係数、 が MA 係数の役回り)。
- 区間幅は条件付き分散から直接:点予測は平均(≈0)、区間は 。ARIMA では分散が累積して単調に広がるのに対し、定常 GARCH では が無条件分散へ収束するので、区間は局面に応じて伸縮しつつ長期では一定幅へ落ち着きます。
- 収束速度は持続性が支配:。 が に近いほど収束が遅く、高ボラ局面の影響が長く先まで残ります。
⚠️ よくある誤解・落とし穴
- 「リターンの ACF が0だから予測不能」ではない:平均は無相関でも分散は予測できる。2乗の ACF を見ずに「予測価値なし」と結論するのは早計です。
- 「点予測(≈0)だけで十分」ではない:ボラティリティ予測の価値は**区間(リスク)**にあります。 の伸縮こそが意思決定(ポジション量・VaR)に効く情報。点予測だけ出すのは本末転倒です。
- 「区間はホライズンとともに必ず広がる」ではない:ARIMA(非定常)はそうですが、定常 GARCH の多期先区間は無条件分散へ収束して一定幅に落ち着きます。さらに、いま高ボラ局面なら先読みで区間がむしろ縮むこともあります(平均回帰)。
- 「Ljung-Box をリターンに当てれば ARCH を検出できる」ではない:ARCH 効果は2乗(または絶対値)系列、あるいは ARMA 残差の2乗に当てて検出します。水準の系列に当てても見えません。
- 「時系列の検証をシャッフルしてよい」ではない:ボラの評価でも時間順(ウォークフォワード)が鉄則。未来情報の漏洩は区間カバレッジを過大評価させます(予測の評価指標と時系列CV)。
関連ノート
- ARCHとGARCHモデル(ARCH/GARCHの定義・パラメータ復元・条件付きボラ)
- 第6章 ボラティリティ 目次
- 定常性と自己相関(ACF・2乗のACFと接続)
- モデル選択と残差診断(残差2乗のARCH効果点検→GARCHへ)
- ARMA・ARIMAモデル(区間が単調に広がる予測との対比)
- 予測の評価指標と時系列CV(ウォークフォワード・カバレッジ)
- 確率過程(マルコフ連鎖・ポアソン過程)(統計・定常過程の土台)
- 時系列分析・予測テキスト 全体目次