GARCH 모델이란?
금융 시장에서 변동성(Volatility)은 단순히 가격이 얼마나 움직이는지를 넘어, 리스크 관리와 포지션 사이징의 핵심 지표입니다. 그런데 변동성은 일정하지 않습니다. 시장이 급변할 때 변동성이 급등하고, 안정기에는 줄어드는 변동성 클러스터링(Volatility Clustering) 현상이 존재합니다.
GARCH(Generalized Autoregressive Conditional Heteroskedasticity) 모델은 이런 시간에 따라 변하는 변동성을 수학적으로 포착하는 계량경제학 모델입니다. 1986년 Tim Bollerslev가 제안한 이 모델은, 과거 수익률의 충격(shock)과 과거 변동성이 현재 변동성에 미치는 영향을 동시에 반영합니다.
GARCH(1,1) 수식 이해
가장 기본적이고 널리 사용되는 GARCH(1,1) 모델의 조건부 분산 방정식은 다음과 같습니다.
σ²(t) = ω + α · ε²(t-1) + β · σ²(t-1)
- σ²(t): t 시점의 조건부 분산 (예측 변동성)
- ω (omega): 장기 평균 분산 관련 상수 (ω > 0)
- α (alpha): 직전 수익률 충격의 영향력 (0 ≤ α < 1)
- β (beta): 직전 변동성의 지속성 (0 ≤ β < 1)
- ε(t-1): t-1 시점의 잔차 (수익률 충격)
- α + β < 1: 정상성(stationarity) 조건
α + β 값이 1에 가까울수록 변동성 충격이 오래 지속됩니다. 비트코인 같은 암호화폐는 이 값이 0.95~0.99로 매우 높아, 한번 변동성이 커지면 상당 기간 유지되는 특성을 보입니다.
파이썬으로 GARCH 모델 구현
파이썬 arch 라이브러리를 사용하면 GARCH 모델을 쉽게 구현할 수 있습니다. 아래는 비트코인 일봉 데이터로 변동성을 예측하는 전체 코드입니다.
import numpy as np
import pandas as pd
import yfinance as yf
from arch import arch_model
import matplotlib.pyplot as plt
# 1. 비트코인 일봉 데이터 수집
btc = yf.download("BTC-USD", start="2020-01-01", end="2026-03-01")
returns = btc["Close"].pct_change().dropna() * 100 # 퍼센트 수익률
# 2. GARCH(1,1) 모델 적합
model = arch_model(returns, vol="Garch", p=1, q=1, dist="t")
result = model.fit(disp="off")
print(result.summary())
# 3. 조건부 변동성 추출
cond_vol = result.conditional_volatility
# 4. 향후 5일 변동성 예측
forecast = result.forecast(horizon=5)
future_var = forecast.variance.iloc[-1]
future_vol = np.sqrt(future_var)
print("향후 5일 예측 변동성(%):")
print(future_vol)
위 코드에서 dist="t"는 Student-t 분포를 사용한다는 의미입니다. 금융 수익률은 정규분포보다 꼬리가 두꺼운(fat-tail) 분포를 보이기 때문에, t-분포를 사용하면 극단적 움직임을 더 잘 반영합니다.
GARCH 변동성을 활용한 매매 전략
GARCH 예측 변동성을 실제 트레이딩에 활용하는 대표적인 방법 3가지를 소개합니다.
1. 변동성 기반 포지션 사이징
예측 변동성이 높을수록 포지션 크기를 줄이고, 낮을수록 늘리는 전략입니다. 리스크 패리티(Risk Parity) 개념과 유사합니다.
def garch_position_size(predicted_vol, target_vol=2.0, max_leverage=3.0):
"""
predicted_vol: GARCH 예측 일일 변동성 (%)
target_vol: 목표 일일 변동성 (%)
"""
leverage = target_vol / predicted_vol
leverage = min(leverage, max_leverage) # 최대 레버리지 제한
leverage = max(leverage, 0.1) # 최소 포지션
return leverage
# 예시: 예측 변동성 4% → 레버리지 0.5x
# 예시: 예측 변동성 1% → 레버리지 2.0x
2. 변동성 레짐 필터
GARCH 변동성의 장기 이동평균을 기준으로 저변동성 레짐과 고변동성 레짐을 구분하고, 레짐에 따라 전략을 전환합니다.
def regime_filter(cond_vol, lookback=60):
"""변동성 레짐 감지"""
vol_ma = cond_vol.rolling(lookback).mean()
vol_std = cond_vol.rolling(lookback).std()
regime = pd.Series("normal", index=cond_vol.index)
regime[cond_vol > vol_ma + vol_std] = "high_vol"
regime[cond_vol < vol_ma - 0.5 * vol_std] = "low_vol"
return regime
# 고변동성 레짐: 추세추종(모멘텀) 전략 유리
# 저변동성 레짐: 평균회귀(역추세) 전략 유리
3. 변동성 돌파 타이밍
GARCH 예측 변동성이 급격히 상승하는 시점을 변동성 돌파 신호로 활용합니다. 변동성이 압축된 상태에서 갑자기 확대되면, 강한 추세가 시작되는 경우가 많습니다.
def vol_breakout_signal(cond_vol, threshold=1.5):
"""변동성 돌파 신호 감지"""
vol_ratio = cond_vol / cond_vol.rolling(20).mean()
signal = (vol_ratio > threshold).astype(int)
return signal
# vol_ratio > 1.5: 최근 20일 평균 대비 50% 이상 변동성 급등
# → 브레이크아웃 가능성 높음, 추세추종 진입 고려
EGARCH와 GJR-GARCH: 비대칭 변동성
기본 GARCH 모델은 양(+)의 충격과 음(-)의 충격을 동일하게 취급합니다. 하지만 실제 시장에서는 하락 충격이 상승 충격보다 변동성을 더 크게 키우는 레버리지 효과(Leverage Effect)가 존재합니다.
이를 반영한 확장 모델이 EGARCH와 GJR-GARCH입니다.
# GJR-GARCH: 하락 충격에 추가 가중치 부여
gjr_model = arch_model(returns, vol="Garch", p=1, o=1, q=1, dist="t")
gjr_result = gjr_model.fit(disp="off")
print(gjr_result.summary())
# EGARCH: 로그 변동성으로 비대칭성 포착
egarch_model = arch_model(returns, vol="EGARCH", p=1, q=1, dist="t")
egarch_result = egarch_model.fit(disp="off")
print(egarch_result.summary())
# gamma(γ) 파라미터가 음수 → 하락 시 변동성이 더 크게 증가
암호화폐 시장에서는 주식 시장만큼 레버리지 효과가 뚜렷하지 않을 수 있지만, GJR-GARCH 모델로 확인해보면 시장 특성을 더 정확히 파악할 수 있습니다.
GARCH 모델 선택과 검증
여러 GARCH 변형 중 최적 모델을 선택하려면 정보 기준(Information Criteria)을 비교합니다.
| 기준 | 설명 | 해석 |
|---|---|---|
| AIC | Akaike Information Criterion | 값이 낮을수록 우수 |
| BIC | Bayesian Information Criterion | 파라미터 수에 더 큰 패널티 |
| Log-Likelihood | 로그 우도 | 값이 높을수록 우수 |
# 모델 비교
models = {
"GARCH(1,1)": arch_model(returns, vol="Garch", p=1, q=1, dist="t"),
"GARCH(2,1)": arch_model(returns, vol="Garch", p=2, q=1, dist="t"),
"GJR-GARCH": arch_model(returns, vol="Garch", p=1, o=1, q=1, dist="t"),
"EGARCH": arch_model(returns, vol="EGARCH", p=1, q=1, dist="t"),
}
for name, m in models.items():
res = m.fit(disp="off")
print(f"{name:15s} AIC={res.aic:.1f} BIC={res.bic:.1f}")
또한 잔차 진단을 통해 모델이 변동성 패턴을 제대로 포착했는지 검증해야 합니다. 표준화 잔차의 자기상관이 사라졌다면 모델이 적절한 것입니다.
실전 적용 시 주의사항
GARCH 모델을 실전 자동매매에 적용할 때 반드시 고려해야 할 사항들입니다.
- 롤링 윈도우 재추정: 파라미터는 시간에 따라 변합니다. 60~120일마다 모델을 재추정하세요.
- 예측 한계: GARCH는 1~5일 단기 예측에 강합니다. 장기 예측은 장기 평균 분산으로 수렴합니다.
- 블랙스완 이벤트: GARCH는 과거 데이터 기반이므로, 전례 없는 극단적 이벤트는 예측하지 못합니다. 별도의 꼬리 위험 헤지 전략이 필요합니다.
- 데이터 빈도: 일봉뿐 아니라 시간봉, 5분봉에도 적용 가능하지만, 고빈도 데이터일수록 노이즈에 주의하세요.
- 다른 모델과 앙상블: GARCH 변동성을 허스트 지수나 시장 레짐 감지와 결합하면 더 강건한 전략을 만들 수 있습니다.
마무리
GARCH 모델은 30년 넘게 금융 시장에서 검증된 변동성 예측 도구입니다. 파이썬 arch 라이브러리 덕분에 구현도 간단합니다. 핵심은 GARCH 예측 변동성을 그 자체로 매매 신호로 쓰기보다, 포지션 사이징, 레짐 필터, 리스크 관리의 입력값으로 활용하는 것입니다. 변동성을 예측할 수 있다면, 수익률을 예측하지 못해도 리스크를 통제할 수 있습니다.