← 기사 목록으로
July 13, 2026
5분 소요

GARCH 예측을 활용한 변동성 타겟팅과 트레이딩

#volatility
#GARCH
#volatility-targeting
#backtesting
#risk
#crypto
#algorithmic-trading

이 시리즈의 첫 세 편은 변동성 예측 방법을 다뤘습니다. Part 1에서는 단변량 GARCH(1,1)을 구축했고, Part 2에서는 GJR과 Student-t 이노베이션으로 레버리지 효과와 팻테일을 추가했으며, Part 3에서는 DCC-GARCH로 시간에 따라 변하는 공분산 행렬 전체를 모델링했습니다. 매번 마지막에는 숫자 하나를 출력했습니다. 바로 내일의 예상 변동성입니다. 그리고 솔직히 말하면, 우리는 거기서 멈췄습니다. 마치 예측을 생산하는 것 자체가 목적인 것처럼요.

하지만 그렇지 않습니다. 변동성 예측은 손익이 아닙니다. 낮은 QLIKE 점수로 돈을 받은 사람은 아무도 없습니다. 예측은 그것이 없었다면 다르게 내렸을 결정을 실제로 바꾸는 바로 그 순간에야 비로소 가치를 갖습니다 — 얼마나 살지, 언제 손절할지, 자본을 얼마나 배분할지. 만약 예측이 포지션을 움직이지 않는다면, 그 통계적 정확도는 개인적인 취미일 뿐입니다.

이번 마지막 편은 그 고리를 닫는 것에 관한 것입니다. Part 1-3의 예측을 가져와 가장 깔끔한 의사결정에 투입합니다. 바로 변동성 타겟팅입니다 — 포트폴리오의 실현 변동성이 일정한 목표치에 도달하도록 포지션 크기를 조절하는 것입니다. 그런 다음 이 블로그가 어떤 개별 모델보다 더 중요하게 여기는 일을 합니다. 바로 정직한 평가입니다. 우리는 GARCH를 단순하지만 강력한 기준선(롤링 실현 변동성, EWMA)과 벤치마킹하고, 진짜 변동성을 결코 관측할 수 없다는 사실에 강건한 손실 함수를 사용하며, 비용을 반영하고 미래 정보 누출이 없는 워크포워드 백테스트를 실행하고, 변동성 타겟팅이 무엇을 주고 무엇을 주지 않는지 솔직하게 밝힙니다. 스포일러: 이는 알파를 만들어내는 것보다 훨씬 더 안정적으로 위험조정수익률을 개선하고 드로다운을 억제합니다.

왜 변동성 타겟팅이 올바른 테스트인가

변동성 예측을 사용하는 더 화려한 방법들도 있습니다 — 옵션 가격 결정, VaR 한도, 동적 헤징 등. 하지만 변동성 타겟팅은 다른 베팅으로 인한 오염이 가장 적은 상태로 예측의 가치를 분리해내는 방법입니다. 아이디어는 하나의 방정식으로 요약됩니다.

시그널이 방향을 암시하는(지금은 단순히 "롱"이라고 하겠습니다) 위험 자산을 보유한다고 합시다. 고정된 포지션 대신, 예측 변동성에 반비례하게 노출을 조절합니다.

wt=σtargetσ^t(그 후 상한 적용)w_t = \frac{\sigma_{\text{target}}}{\hat{\sigma}_{t}} \quad \text{(그 후 상한 적용)}

여기서 σ^t\hat{\sigma}_t는 다음 기간 변동성에 대한 예측치이며(오직 tt까지의 데이터만 사용), σtarget\sigma_{\text{target}}은 전략이 목표로 하는 연율화 변동성입니다 — 예를 들어 15% 또는 20%. 모델이 조용한 시장을 예측하면 1.0을 향해(혹은 그 이상으로) 레버리지를 올리고, 폭풍을 예측하면 축소합니다. 조절된 포지션의 실현 변동성은 1차 근사로

Vol(wtrt+1)=wtσt+1=σtargetσ^tσt+1σtarget\text{Vol}(w_t r_{t+1}) = w_t \, \sigma_{t+1} = \frac{\sigma_{\text{target}}}{\hat\sigma_t}\, \sigma_{t+1} \approx \sigma_{\text{target}}

이 됩니다. σ^tσt+1\hat\sigma_t \approx \sigma_{t+1}일 때 항상 그렇습니다. 즉 이 전체 훈련의 품질은 단 하나에 달려 있습니다. 예측치 σ^t\hat\sigma_t가 다음 기간의 실제 변동성 σt+1\sigma_{t+1}에 얼마나 가까운가입니다. 더 나은 예측은 더 평탄한 실현 변동성 프로파일을 만들어내고 — 이후에 살펴보겠지만 — 더 나은 샤프 비율을 만들어냅니다. 이것이 이것이 올바른 테스트인 이유입니다. 예측은 장식이 아닙니다. 그것은 분모입니다.

왜 이것이 샤프를 높이고 드로다운을 통제하는가

두 가지 실증적 사실이 여기서 핵심 역할을 합니다.

변동성은 수익률보다 훨씬 더 예측 가능합니다. 내일 BTC 수익률의 방향은 일간 빈도에서 동전 던지기에 가깝지만, 크기는 그렇지 않습니다. 변동성은 군집을 이룹니다 — 큰 움직임 다음에 큰 움직임이 이어집니다 — 이것이 GARCH가 존재하는 이유 자체입니다(Part 1에서 이를 인코딩하는 분산에서의 AR(1) 구조를 유도했습니다). 하루 앞선 분산 예측의 R2R^2가 0.4-0.6인 것은 흔한 일이지만, 수익률에 대해 같은 숫자가 나온다면 그것은 르네상스 급의 시그널일 것입니다. 변동성 타겟팅은 예측 가능한 양을 활용하면서 예측 불가능한 양에 대해서는 불가지론적 입장을 유지합니다.

샤프 비율은 시간에 걸쳐 일정하지 않으며, 변동성이 급등할 때 하락합니다. 크립토의 고변동성 국면 — 디레버리징 캐스케이드, 거래소 파산, 모든 것이 30% 갭을 만드는 날들 — 은 대체로 위험 단위당 수익이 더 나쁜 경향이 있지, 더 좋아지는 것이 아닙니다. 예측 변동성이 높을 때 정확히 노출을 기계적으로 줄임으로써, 드로다운에 가장 크게 기여하고 복리 수익에는 가장 적게 기여하는 기간의 비중을 낮추게 됩니다. Moreira와 Muir(2017)는 주식에서 변동성 관리 포트폴리오 — 바로 이 1/σ21/\sigma^2 조절 — 가 샤프 비율을 높이고 비관리 팩터 대비 양의 알파를 생성한다는 것을 보였습니다. 그 메커니즘은 마법이 아닙니다. 예측 가능하게 격동적인 구간에 고정된 달러 포지션을 유지하기를 거부하는 것일 뿐입니다.

드로다운 이점은 훨씬 더 직접적입니다. 최대 드로다운은 포지션 수익률 분포의 꼬리에 지배됩니다. wtrt+1w_t r_{t+1}의 변동성이 σtarget\sigma_{\text{target}} 근처에 고정되어 있으므로, 변동성 폭발 시 고정 명목 전략이 겪는 두터운 왼쪽 꼬리는 압축됩니다. 이미 진입 시점에서 작게 들어가 있었기 때문입니다. 변동성 타겟팅이 폭락을 예측하는 것은 아니지만, 시장이 요동칠 때 체계적으로 노출을 줄이며, 요동은 곧 폭락이 일어나는 때입니다.

Kelly 및 부분 사이징과의 관계

변동성 타겟팅은 Kelly 기준의 사촌 격입니다. 기대 초과 수익 μ\mu와 분산 σ2\sigma^2을 가진 단일 자산의 경우, 성장 최적(풀 Kelly) 비율은

f=μσ2.f^\star = \frac{\mu}{\sigma^2}.

샤프 비율 μ/σ\mu/\sigma가 대략 일정하다고 가정하면 — 강한 가정이지만 "시장은 위험에 안정적인 가격을 지불한다"는 명제에 암묵적으로 내포된 가정입니다 — μ=Sσ\mu = S\sigma이고 f=S/σf^\star = S/\sigma가 되는데, 이는 정확히 σtarget=S(Kelly fraction)\sigma_{\text{target}} = S \cdot (\text{Kelly fraction})인 변동성 타겟팅입니다. 다시 말해, 변동성 타겟팅은 기대 수익이 변동성에 비례한다는 가정 하의 Kelly 사이징입니다. 우리는 풀 Kelly와 부분 Kelly, 그리고 왜 제정신인 사람이라면 아무도 풀 Kelly로 트레이딩하지 않는지를 Kelly 기준과 전략 사이징에서 다뤘습니다. 거기서 얻은 실용적인 교훈은 여기에도 이어집니다. 이론적 사이즈의 일부만 사용하십시오. 분모(변동성 예측)의 추정 오차, 특히 분자(기대 수익)의 추정 오차 때문에 풀 사이징은 위험할 정도로 공격적이 됩니다.

염두에 둘 두 가지 연결점이 더 있습니다. 첫째, 변동성 타겟팅은 수익률의 대칭적 분산에 기반해 사이징하지만, 크립토의 페이오프는 대칭적이지 않습니다 — 레버리지와 청산이 개입되면 20% 하락일의 비용은 20% 상승일의 거울상이 아닙니다. 우리는 이 비대칭성을 손익 비대칭성에서 직접 다뤘으며, GJR/EGARCH 예측(Part 2)은 음의 충격에 더 크게 반응함으로써 이를 이미 σ^t\hat\sigma_t에 어느 정도 반영합니다. 둘째, 변동성 예측은 점 추정치이며, 더 완전한 위험 관점은 여기에 구간을 붙입니다. 트레이딩을 위한 등각 예측은 모델 출력을 분포에 무관한 구간으로 바꿔 사이징에 활용하는 방법을 보여주는데, 이는 이 글의 정직한 평가라는 주제와 자연스럽게 짝을 이룹니다.

경쟁자들: GARCH가 이겨야 할 대상

여기서부터가 실제 평가를 데모와 구별 짓는 규율입니다. GARCH에게 왕관을 씌우기 전에, 값싸고 명백하며 놀랍게도 이기기 어려운 상대들을 붙여줘야 합니다. 정교한 GJR-t 모델이 다섯 줄짜리 EWMA를 능가하지 못한다면, 여러분은 가치 있는 무언가를 배웠고 프로덕션의 복잡성을 크게 줄일 수 있게 된 것입니다.

우리는 다음 기간 변동성에 대한 네 가지 예측기를 벤치마킹합니다.

(a) 후행 실현 변동성 (롤링 표준편차)

가장 단순한 예측: 내일의 변동성은 최근 nn개 일간 수익률의 표본 표준편차와 같습니다.

σ^tRV=1n1i=1n(rti+1rˉ)2\hat\sigma_{t}^{\text{RV}} = \sqrt{\frac{1}{n-1}\sum_{i=1}^{n}\bigl(r_{t-i+1}-\bar r\bigr)^2}

이는 하이퍼파라미터(윈도우 nn, 보통 20-60일) 하나만 있고 모델은 없습니다. 결함은 윈도우 내 모든 관측치가 동일한 가중치를 받다가 윈도우를 벗어나면 갑자기 절벽에서 떨어진다는 점입니다 — "고스팅" 또는 "에코" 효과라 불리는데, 단 하루의 폭락일이 정확히 nn일 동안 예측치를 부풀렸다가 시장이 실제로 진정되었는지 여부와 상관없이 하룻밤 사이에 사라져 버립니다.

(b) EWMA / RiskMetrics (λ=0.94\lambda = 0.94)

지수가중이동평균은 오래된 제곱 수익률에 기하급수적으로 감소하는 가중치를 부여함으로써 에코 문제를 해결합니다.

σ^t2=λσ^t12+(1λ)rt2\hat\sigma_{t}^{2} = \lambda\,\hat\sigma_{t-1}^{2} + (1-\lambda)\,r_{t}^{2}

이것이 RiskMetrics(J.P. Morgan, 1996) 추정치입니다. 일간 데이터에 대한 표준값 λ=0.94\lambda = 0.94를 사용하면 유효 메모리는 대략 1/(1λ)171/(1-\lambda) \approx 17일이지만, 감소는 부드럽습니다 — 절벽이 없습니다. EWMA가 실제로 무엇인지 주목하십시오. 이는 **ω=0\omega = 0이고 α+β=1\alpha + \beta = 1인 적분된 GARCH(1,1)**입니다. 즉 평균회귀도 없고 장기 분산도 없는 GARCH입니다. λ=0.94\lambda = 0.94를 받아들이면 자유 파라미터가 전혀 없으며, 이 글 전체에서 가장 강력한 단일 기준선입니다. "GARCH가 X를 이긴다"는 논문들 중 상당수가 표본 외에서 EWMA를 조용히 이기지 못합니다.

import numpy as np
import pandas as pd

def ewma_vol(returns: pd.Series, lam: float = 0.94, sigma0: float | None = None) -> pd.Series:
    """RiskMetrics EWMA conditional volatility (returns in decimal, e.g. 0.03).

    sigma2_t = lam * sigma2_{t-1} + (1 - lam) * r_t^2
    Returns a series aligned to `returns` where value at t uses info up to t.
    """
    r2 = np.square(returns.values)
    var = np.empty_like(r2)
    var[0] = sigma0**2 if sigma0 is not None else r2[0]
    for t in range(1, len(r2)):
        var[t] = lam * var[t - 1] + (1.0 - lam) * r2[t - 1]  # note: r_{t-1}, no look-ahead
    return pd.Series(np.sqrt(var), index=returns.index, name="ewma_vol")

사람들을 넘어뜨리는 한 가지 미묘한 점은 기간 tt대한 예측치(즉 tt 동안 보유되는 포지션을 사이징하는 데 쓸 수 있는 예측치)는 tt 이전에 관측된 수익률로부터 구축되어야 한다는 점입니다. 위 재귀식에서 var[t]r2[t-1]을 사용하므로, 이 시리즈는 진짜 한 걸음 앞선 예측입니다. 이 인덱스를 올바르게 맞추는 것이 백테스트와 환상을 가르는 차이입니다 — 워크포워드 절에서 더 자세히 다루겠습니다.

(c) GARCH(1,1)과 GJR-t (Part 1-2)

우리의 주인공들입니다. 표준 GARCH(1,1)은

σt2=ω+αϵt12+βσt12,ω>0, α,β0, α+β<1\sigma_t^2 = \omega + \alpha\, \epsilon_{t-1}^2 + \beta\,\sigma_{t-1}^2, \qquad \omega>0,\ \alpha,\beta\ge0,\ \alpha+\beta<1

이며, 장기 분산은 σˉ2=ω/(1αβ)\bar\sigma^2 = \omega/(1-\alpha-\beta)이고 한 걸음 앞선 예측은 재귀식에서 곧바로 도출됩니다(Part 1). GJR-GARCH 확장은 레버리지 항을 추가하여 음의 충격이 양의 충격보다 분산을 더 크게 높이도록 합니다.

σt2=ω+(α+γ1[ϵt1<0])ϵt12+βσt12\sigma_t^2 = \omega + (\alpha + \gamma\, \mathbb{1}[\epsilon_{t-1}<0])\,\epsilon_{t-1}^2 + \beta\,\sigma_{t-1}^2

이를 크립토의 팻테일을 다루기 위한 Student-t 이노베이션과 결합한 것이 Part 2의 GJR-t입니다. GARCH가 EWMA를 이길 수 있는 이유는 평균회귀입니다. 충격 이후 GARCH는 α+β\alpha+\beta가 지배하는 속도로 예측치를 σˉ2\bar\sigma^2을 향해 다시 끌어당기지만, EWMA는(적분된 성질 때문에) 결코 되돌아가지 않습니다. 변동성이 급등했다가 정상화되는(흔한 경우) 상황에서는 GARCH의 예측치가 더 빠르고 정확하게 되돌아갑니다. 변동성이 진정으로 지속적일 때는 둘 사이의 차이가 거의 없습니다.

(d) 실현 분산에 대한 HAR-RV (인트라데이 데이터가 있는 경우)

인트라데이 바가 있다면 — 그리고 24/7 크립토 시장에서는 거의 항상 그렇습니다 — 일간 제곱 수익률보다 훨씬 노이즈가 적은 변동성 프록시를 구축할 수 있습니다. 바로 실현 분산, 하루 동안의 인트라데이 제곱 수익률의 합입니다.

RVt=i=1Mrt,i2(예: M=288개의 5분봉)RV_t = \sum_{i=1}^{M} r_{t,i}^2 \qquad (\text{예: } M = 288 \text{개의 5분봉})

Corsi(2009)의 이질적 자기회귀(Heterogeneous Autoregressive) 모델은 과거 RVRV의 일간, 주간, 월간 평균으로부터 내일의 실현 분산을 예측합니다 — 세 개의 회귀변수로 장기 기억 지속성을 포착하는, 투박하지만 놀라울 만큼 효과적인 방법입니다.

RVt+1=β0+βdRVt+βwRVt(5)+βmRVt(22)+ut+1RV_{t+1} = \beta_0 + \beta_d\, RV_t + \beta_w\, \overline{RV}_t^{(5)} + \beta_m\, \overline{RV}_t^{(22)} + u_{t+1}

여기서 RVt(5)\overline{RV}_t^{(5)}RVt(22)\overline{RV}_t^{(22)}는 일간 RVRV의 후행 5일 및 22일 평균입니다. 이는 단순한 OLS 회귀이며, 더 고품질의 인트라데이 프록시를 활용하고, 넷 중 가장 우수한 일간 변동성 예측기인 경우가 많습니다 — 종종 GARCH를 이기는데, 이는 정확히 RVRVr2r^2보다 더 깨끗한 타겟이기 때문입니다.

import numpy as np
import pandas as pd

def realized_variance(intraday_returns: pd.Series, day_index) -> pd.Series:
    """Daily realized variance = sum of squared intraday (log) returns per day.
    `intraday_returns` indexed by timestamp; `day_index` maps to calendar day.
    """
    return intraday_returns.pow(2).groupby(day_index).sum()

def har_features(rv: pd.Series) -> pd.DataFrame:
    """Build HAR regressors from a daily realized-variance series."""
    df = pd.DataFrame({"rv": rv})
    df["rv_d"] = df["rv"].shift(1)                          # yesterday
    df["rv_w"] = df["rv"].shift(1).rolling(5).mean()        # trailing week
    df["rv_m"] = df["rv"].shift(1).rolling(22).mean()       # trailing month
    df["target"] = df["rv"]                                 # predict today's RV
    return df.dropna()

def fit_har(rv: pd.Series):
    """Fit HAR-RV by OLS. Returns (coef_dict, predict_fn)."""
    df = har_features(rv)
    X = np.column_stack([np.ones(len(df)), df["rv_d"], df["rv_w"], df["rv_m"]])
    y = df["target"].values
    beta, *_ = np.linalg.lstsq(X, y, rcond=None)
    names = ["const", "rv_d", "rv_w", "rv_m"]

    def predict(rv_d, rv_w, rv_m):
        return float(beta @ np.array([1.0, rv_d, rv_w, rv_m]))

    return dict(zip(names, beta)), predict

log-HAR에 대해 한 가지 짚어두면, RVRV는 오른쪽으로 치우쳐 있고 항상 양수이기 때문에, 많은 실무자들이 logRVt+1\log RV_{t+1}을 log HAR 특성에 대해 회귀시킵니다. 이는 적합도를 개선하고 양의 예측치를 보장합니다. 다시 지수화할 때는 절반 분산 Jensen 보정을 추가해야 합니다. RV^=exp(y^+12σ^u2)\widehat{RV} = \exp(\hat{y} + \tfrac{1}{2}\hat\sigma_u^2). 그렇지 않으면 체계적으로 과소 예측하게 됩니다.

네 가지 예측기 — RV, EWMA, GARCH/GJR-t, HAR — 를 손에 쥐었으니, 질문은 이렇게 됩니다. 그것들이 모두 예측하려는 대상 자체를 결코 볼 수 없는데, 어떤 것이 최선인지 어떻게 판단할까요?

변동성 예측을 정직하게 평가하기

이것이 이 글의 핵심 가르침이므로, 천천히 짚어보겠습니다.

예측치 σ^t2\hat\sigma_t^2를 진짜 조건부 분산 σt2\sigma_t^2와 비교하고 싶을 것입니다. 하지만 σt2\sigma_t^2잠재적인 양입니다 — 데이터 생성 과정의 파라미터이며, 결코 직접 관측되지 않습니다. 우리가 얻는 것은 하루에 하나의 실현된 수익률뿐입니다. 그러므로 모든 변동성 평가는 사실상 예측치를 진실에 대한 노이즈 낀 프록시와 비교하는 것입니다. 두 가지 표준 프록시는 다음과 같습니다.

  • 제곱 수익률 rt2r_t^2. 평균 0인 모델 하에서 σt2\sigma_t^2에 대해 불편(unbiased)입니다(E[rt2Ft1]=σt2\mathbb{E}[r_t^2 \mid \mathcal{F}_{t-1}] = \sigma_t^2). 하지만 극도로 노이즈가 많습니다. 단 하루의 수익률은 표준편차에 대한 단일 관측치 추정입니다. 프록시 rt2r_t^2는 진짜 변동성이 높을 때조차 0(잔잔한 날)일 수 있고, 운 좋은 꼬리 사건이 발생한 날에는 거대할 수 있습니다.
  • 실현 분산 RVtRV_t, 인트라데이 데이터로부터 계산됩니다. 훨씬 노이즈가 적습니다 — 인트라데이 샘플링이 개별 관측치의 특이 노이즈를 평균해내기 때문입니다 — 이것이 바로 HAR-RV가 작동하는 이유이며, 인트라데이 데이터가 조금이라도 있다면 RVRV를 프록시로 사용해야 하는 이유입니다.

거의 모든 사람을 걸려 넘어지게 하는 미묘한 점은 이것입니다. 프록시가 노이즈가 있기 때문에, 손실 함수의 선택은 결코 무해하지 않습니다. 잘못된 손실로 두 예측치의 순위를 매기면 노이즈 낀 프록시가 순위를 뒤집어, 더 나쁜 예측이 더 낫다고 알려줄 수 있습니다. Patton(2011)은 어떤 손실 함수가 "강건한지"를 정확히 규명했습니다. 즉 노이즈 낀 프록시에 대한 기대 손실로 예측치의 순위를 매길 때, 진짜(관측 불가능한) 분산에 대해 얻었을 것과 동일한 순위를 주는 성질을 가진 손실 함수입니다. 특정한 부류의 손실 함수만이 이 자격을 갖습니다. 실무에서 중요한 두 가지가 있습니다.

MSE 대 QLIKE

분산에 대한 평균제곱오차는

LMSE(σ2,h)=(σ2h)2L_{\text{MSE}}(\sigma^2, h) = (\sigma^2 - h)^2

여기서 h=σ^2h = \hat\sigma^2는 예측치이고 σ2\sigma^2r2r^2 또는 RVRV로 프록시됩니다. MSE는 Patton의 의미에서 강건합니다(순위가 프록시-일관적입니다). 하지만 대칭적이고 스케일에 의존적입니다. 동일한 절댓값 크기의 과대 예측과 과소 예측을 동일하게 벌하며, 고변동성 기간의 오차에 조용한 기간의 오차보다 훨씬 큰 가중치를 부여합니다. 조용한 95%의 날들은 정확히 맞추지만 위기의 사흘 동안 분산 예측이 폭발하는 모델은 MSE 하에서 끔찍해 보일 것입니다. 설사 그 위기 시 행동이 실제로 우리가 원하는 것이라 하더라도 말입니다.

QLIKE(준-우도) 손실은 실무의 주력입니다.

LQLIKE(σ2,h)=σ2hlogσ2h1L_{\text{QLIKE}}(\sigma^2, h) = \frac{\sigma^2}{h} - \log\frac{\sigma^2}{h} - 1

이는 분산에 대한 가우시안 우도가 함의하는 손실이며, Patton의 의미에서도 강건하고, 변동성에 대해 선호되는 선택이 되게 하는 두 가지 특성을 가지고 있습니다. 첫째, 올바른 방향으로 비대칭적입니다. 분산의 과소예측을 과대예측보다 더 크게 벌합니다. 리스크 매니저나 변동성 타겟터에게는 이것이 올바른 비대칭성입니다. 변동성을 과소 예측한다는 것은 그것이 중요해지기 직전에 과도한 사이즈를 짊어졌다는 뜻이며, 이는 비용이 큰 오류입니다. 둘째, (대략적으로) 스케일 불변입니다. 비율 σ2/h\sigma^2/h에 의존하기 때문에 10%의 예측 오차는 조용한 날이든 위기의 날이든 비슷한 비용을 지불하게 되며, 그래서 평가가 MSE처럼 소수의 고분산 관측치에 좌우되지 않습니다. 프록시의 이분산성에 대한 그 강건함이야말로, 변동성이 격렬하게 변한다는 것이 핵심일 때 정확히 필요한 것입니다.

LQLIKE0L_{\text{QLIKE}} \ge 0이며, h=σ2h = \sigma^2일 때만 등호가 성립함에 유의하십시오. MSE와 마찬가지로 낮을수록 좋습니다.

import numpy as np

def qlike(proxy: np.ndarray, forecast_var: np.ndarray) -> np.ndarray:
    """Per-observation QLIKE loss. `proxy` is r^2 or RV (a variance proxy),
    `forecast_var` is h = sigma_hat^2. Both strictly positive, same units.
    """
    ratio = proxy / forecast_var
    return ratio - np.log(ratio) - 1.0

def mse_var(proxy: np.ndarray, forecast_var: np.ndarray) -> np.ndarray:
    """Per-observation MSE on the variance scale."""
    return np.square(proxy - forecast_var)

운영상의 경고 두 가지가 있습니다. 프록시와 예측치를 동일한 단위로 유지하십시오(둘 다 일간 분산이거나 둘 다 연율화된 값이어야 합니다). 그렇지 않으면 비율은 의미가 없어집니다. 그리고 forecast_var가 절대 0에 닿지 않도록 하십시오 — 작은 하한값으로 클리핑하십시오. log0\log 0은 전체 평균을 오염시킬 것입니다.

Mincer-Zarnowitz 회귀

손실 값 하나는 어느 예측치가 더 나은지 알려주지만, 예측치가 어떻게 틀렸는지는 알려주지 않습니다. Mincer-Zarnowitz(1969) 회귀가 그것을 알려줍니다. 프록시를 예측치에 대해 회귀시킵니다.

rt2  =  a+bσ^t2+ut.r_t^2 \;=\; a + b\,\hat\sigma_t^2 + u_t.

최적이고 편향되지 않은 예측치 하에서는 a=0a = 0이고 b=1b = 1입니다. 평균적으로 실현 분산이 예측치와 같다는 뜻입니다. 편차는 병리를 진단해줍니다.

  • b<1b < 1이고 a>0a > 0: 예측치가 지나치게 변동적이라는 전형적인 신호입니다 — 과잉 반응하여 완전히 실현되지 않는 극단값을 예측합니다. 원 제곱 수익률에 크게 의존하는 모델에서 매우 흔합니다.
  • b>1b > 1: 예측치가 과소 반응합니다. 진짜 분산에 충분히 비례하지 않습니다.
  • 낮은 회귀 R2R^2: a,ba, b가 평균적으로 괜찮아 보여도, 예측치가 일별 분산을 제대로 추적하지 못합니다. 프록시가 워낙 노이즈가 많기 때문에, r2r^2에 대한 MZ R2R^2가 종종 0.05-0.20에 불과해도 놀라지 마십시오. RVRV에 대해서는 훨씬 높을 것입니다. r2r^2에 대한 R2R^2는 예측이 아무리 좋아도 순전히 프록시 노이즈 때문에 1보다 훨씬 낮은 범위에 갇혀 있습니다.

H0:(a,b)=(0,1)H_0: (a,b) = (0,1)에 대한 결합 FF-검정은 공식적인 캘리브레이션 검사를 제공합니다. 실무에서는 MZ를 예측치를 이해하기 위한 진단 도구로 사용하고, QLIKE를 예측치의 순위를 매기는 데 사용하십시오.

Diebold-Mariano: 차이가 진짜인가?

GARCH의 평균 QLIKE가 0.183이고 EWMA는 0.191이라고 합시다. GARCH가 "이겼습니다." 하지만 0.008은 진짜 우위일까요, 표본 노이즈일까요? Diebold-Mariano(1995) 검정은 정확히 이 질문에 답합니다. 기간별 손실 차이를 정의합니다.

dt=L(proxyt,htA)L(proxyt,htB)d_t = L(\text{proxy}_t, h^A_t) - L(\text{proxy}_t, h^B_t)

두 예측치 AABB에 대해(여기서 LL = QLIKE). 귀무가설은 동등한 예측 정확도, H0:E[dt]=0H_0: \mathbb{E}[d_t] = 0입니다. 통계량은 평균 차이를 장기(HAC) 표준오차로 표준화한 것입니다. dtd_t가 계열 상관을 가지기 때문입니다.

DM=dˉLRV^(dt)/T  d  N(0,1)\text{DM} = \frac{\bar d}{\sqrt{\widehat{\mathrm{LRV}}(d_t)/T}} \;\xrightarrow{d}\; \mathcal{N}(0,1)

여기서 LRV^\widehat{\mathrm{LRV}}는 Newey-West 유형의 장기 분산 추정치입니다. DM 통계량이 ±1.96\pm 1.96을 넘으면 5% 수준에서 동등한 정확도라는 귀무가설을 기각합니다. 결정적으로, DM은 중첩된 모델이 아니라 예측치에 대한 검정이며, dtd_t에 대한 순진한 tt-검정이라면 무시했을 계열 의존성을 처리합니다.

import numpy as np
from scipy import stats

def diebold_mariano(loss_a: np.ndarray, loss_b: np.ndarray, h: int = 1):
    """Diebold-Mariano test of equal predictive accuracy.
    loss_a, loss_b: per-period losses (e.g. QLIKE) for forecasts A and B.
    h: forecast horizon; Newey-West lag = h - 1 (>=0), plus a small-sample buffer.
    Returns (DM_stat, p_value). Negative DM => A has lower loss (A better).
    """
    d = np.asarray(loss_a) - np.asarray(loss_b)
    T = len(d)
    d_bar = d.mean()

    lag = max(h - 1, 0)
    gamma0 = np.mean((d - d_bar) ** 2)
    lrv = gamma0
    for k in range(1, lag + 1):
        w = 1.0 - k / (lag + 1)
        cov = np.mean((d[k:] - d_bar) * (d[:-k] - d_bar))
        lrv += 2.0 * w * cov

    dm = d_bar / np.sqrt(lrv / T)

    adj = np.sqrt((T + 1 - 2 * h + h * (h - 1) / T) / T)
    dm *= adj
    p = 2.0 * (1.0 - stats.t.cdf(abs(dm), df=T - 1))
    return float(dm), float(p)

그 주석 안의 예시 결과는 정직하고 흔한 결과이며, 이 절이 존재하는 전체 이유입니다. GARCH는 종종 EWMA보다 약간 낮은 평균 손실을 기록하지만, 그 우위가 DM 유의성 기준을 넘지 못하는 경우도 그만큼 자주 있습니다. 평균 QLIKE만 보고한다면, DM 검정이라면 기각했을 우위를 스스로 확신하게 될 것입니다. DM 통계량을 보고하십시오. 이는 전략 수익률에 대해 강건한 우위 없음에 대한 정직한 평가에서 적용한 것과 동일한 규율입니다 — 벤치마크를 이기는 점 추정치는 그것이 노이즈가 아님을 배제하기 전까지는 우위가 아닙니다.

백테스트: 워크포워드 변동성 타겟팅 전략

이제 두 절반 — 예측기와 사이징 규칙 — 을 결합하여 전략으로 만들고, 의미 있는 유일한 방식으로 평가합니다. 즉 워크포워드, 표본 외, 비용 반영입니다.

전략은 의도적으로 단순합니다. 결과를 정교한 시그널이 아니라 변동성 예측 자체의 공로로 돌릴 수 있게 하기 위해서입니다. 롱 전용, 변동성 타겟팅 BTC. 매일 다음 날 변동성을 예측하고, 포지션을 wt=min(σtarget/σ^t, wmax)w_t = \min(\sigma_{\text{target}}/\hat\sigma_t,\ w_{\max})로 설정하고, 밤새 보유한 뒤 반복합니다. 롱/플랫 변형은 추세 필터가 음수일 때 포지션을 차단합니다. 소규모 포트폴리오 변형은 Part 3의 DCC 공분산 행렬을 단일 자산의 분산 대신 사용해 사이징합니다. 여기서는 롱 전용 사례를 온전히 서술하고 확장 버전은 짧게 언급합니다.

워크포워드 메커니즘과 미래 정보 누출 금지 계약

이 백테스트의 가장 중요한 단일 속성은 t+1t+1일의 포지션을 사이징하는 데 사용되는 모든 양이 tt일 종가 시점에서 이용 가능한 데이터만으로 계산 가능하다는 것입니다. GARCH 파라미터는 tt에서 끝나는 롤링 윈도우로 재추정됩니다. 예측치는 그 적합으로부터 나온 한 걸음 앞선 σ^t+1\hat\sigma_{t+1}입니다. 포지션은 그 예측치로부터 설정됩니다. 그리고 얻는 수익은 wt+1rt+1w_{t+1} r_{t+1}이며, 여기서 rt+1r_{t+1}은 모델이 결코 보지 못한 다음 날의 수익률입니다. 전체 표본으로 GARCH를 적합시킨 후 과거를 "예측"하는 것은 사람들이 우연히 훌륭한 백테스트를 조작하게 되는 가장 흔한 방법입니다. 우리는 이 미래 정보 누출 함정과 일반적인 방법론을 워크포워드 최적화에서 다뤘습니다.

import numpy as np
import pandas as pd
from arch import arch_model

def walk_forward_voltarget(
    returns: pd.Series,          # daily log returns in decimal (e.g. 0.021)
    proxy_var: pd.Series,        # variance proxy aligned to returns (RV or r^2)
    target_vol_annual: float = 0.20,
    window: int = 750,           # rolling estimation window (days)
    refit_every: int = 5,        # refit GARCH weekly, forecast daily (cost saver)
    w_max: float = 3.0,          # leverage cap
    cost_bps: float = 5.0,       # per-unit-turnover cost in basis points
    ann: int = 365,              # crypto trades 365 days/yr
):
    """Long-only vol-targeted BTC, GARCH(1,1)-t forecasts, strictly walk-forward.
    Returns a DataFrame with position, forecast vol, net returns, and turnover.
    """
    idx = returns.index
    target_daily = target_vol_annual / np.sqrt(ann)

    fcast_vol = pd.Series(index=idx, dtype=float, name="fcast_vol")
    last_res = None

    for i in range(window, len(returns) - 1):
        if (i - window) % refit_every == 0 or last_res is None:
            train = returns.iloc[i - window:i + 1] * 100.0   # scale for the optimizer
            am = arch_model(train, mean="Constant", vol="GARCH",
                            p=1, o=1, q=1, dist="t")           # GJR-t, Part 2
            last_res = am.fit(disp="off")

        f = last_res.forecast(horizon=1, reindex=False)
        var_next = f.variance.values[-1, 0] / (100.0 ** 2)    # unscale
        fcast_vol.iloc[i + 1] = np.sqrt(var_next)

    raw_w = (target_daily / fcast_vol).clip(upper=w_max)
    position = raw_w.shift(0)                                  # w_{i+1} known at close i
    gross_ret = position * returns                            # earned on day i+1

    turnover = position.diff().abs().fillna(0.0)
    cost = turnover * (cost_bps / 1e4)
    net_ret = (gross_ret - cost).dropna()

    out = pd.DataFrame({
        "position": position,
        "fcast_vol": fcast_vol,
        "gross_ret": gross_ret,
        "turnover": turnover,
        "net_ret": net_ret,
    }).dropna()
    return out

def performance_stats(net_ret: pd.Series, ann: int = 365) -> dict:
    """Sharpe, realized vol, max drawdown, CAGR, annual turnover."""
    mu = net_ret.mean() * ann
    sigma = net_ret.std() * np.sqrt(ann)
    sharpe = mu / sigma if sigma > 0 else np.nan
    equity = (1.0 + net_ret).cumprod()
    peak = equity.cummax()
    max_dd = (equity / peak - 1.0).min()
    cagr = equity.iloc[-1] ** (ann / len(net_ret)) - 1.0
    return {
        "sharpe": round(sharpe, 2),
        "realized_vol": round(sigma, 3),
        "max_drawdown": round(max_dd, 3),
        "cagr": round(cagr, 3),
    }

겉보기보다 훨씬 중요한 몇 가지 구현 노트가 있습니다.

  • 옵티마이저를 위한 스케일링. arch 적합은 수익률이 퍼센트 단위일 때 수치적으로 더 안정적입니다. 그래서 * 100을 하고 분산을 다시 스케일 조정할 때 대응하는 / 100**2를 해줍니다. 이 재조정을 잊으면 목표 변동성이 10,000배 어긋나게 됩니다.
  • 재적합 주기. 매일 GARCH 파라미터를 재추정하는 것은 비용이 많이 들고 거의 아무것도 더해주지 않습니다 — 파라미터는 주 단위로 안정적입니다. 매주 재적합하면서(refit_every=5) 매일 예측하는 것(재귀식은 재적합 없이도 새 수익률로부터 σt2\sigma_t^2를 업데이트합니다)이 표준적인 타협안입니다. 이는 결합 위험을 위한 코퓰라 모델의 파이프라인에서 다룬 캐싱 조언을 그대로 반영합니다.
  • 상한 wmaxw_{\max}는 장식이 아닙니다. 완전히 조용한 국면에서 예측 변동성이 붕괴하면, σtarget/σ^t\sigma_{\text{target}}/\hat\sigma_t는 5배, 10배 레버리지로 폭발할 수 있습니다. 상한이 없는 변동성 타겟팅은 변동성 체제 전환 직전 — 예측이 가장 크게 틀릴 것 같은 바로 그 순간 — 에 기꺼이 재앙적인 레버리지를 안겨줄 것입니다. 상한을 정하고(여기서는 3배), 이 상한이 뒤늦게 돌아보면 가장 위험했던 가장 조용한 기간에 정확히 발동한다는 점을 인식하십시오.
  • 비용은 회전율에 비례하며, 변동성 타겟팅은 회전율 제조기입니다. 예측치의 모든 흔들림이 포지션을 다시 사이징합니다. 예측치가 들쭉날쭉한 저변동성 자산에서는 매일 매매를 반복할 수 있습니다. cost_bps 항은 사소한 반올림 세부사항이 아닙니다. 회전율이 높은 변동성 타겟팅 전략에서는 총 샤프 개선분의 상당 부분을 잠식할 수 있습니다.

출력이 어떻게 보이는가 (예시)

여러 해에 걸친 BTC 일간 데이터에서 이를 실행하여 네 가지 예측기를 사이징 분모로 비교하면, 다음과 같은 형태의 표를 얻는 경향이 있습니다. 아래 숫자는 예시입니다 — 전형적인 패턴을 보여주기 위해 손으로 고른 것이지, 실제 백테스트의 출력이 아닙니다 — 하지만 순서와 크기는 실무자들이 보고하는 것을 대표합니다.

사이징 예측기 샤프 실현 변동성 목표 변동성 최대 드로다운 연간 회전율
고정 명목(타겟팅 없음) 0.71 0.68 -0.78 0.1배
롤링 RV (60일) 0.94 0.24 0.20 -0.41 12배
EWMA (λ=0.94\lambda=0.94) 1.02 0.21 0.20 -0.35 19배
GARCH(1,1)-t 1.05 0.21 0.20 -0.33 22배
HAR-RV (인트라데이 프록시) 1.09 0.20 0.20 -0.31 20배

구축할 가치가 있는 두 가지 변형

롱 전용 사례는 예측치를 분리해내지만, 명시적으로 보여줄 만큼 흔한 두 가지 확장이 있습니다.

추세 게이트를 적용한 롱/플랫. 변동성 타겟팅은 포지션 크기를 조절하지만 방향에 대한 견해는 없습니다 — 항상 롱입니다. 값싸고 정직한 개선책은 느린 추세 필터가 음수로 전환될 때 포지션을 차단하는 것입니다. 그래서 상승 추세에서만 변동성 타겟팅된 롱을 보유하고 그렇지 않으면 플랫으로 앉아 있습니다. 이는 사이징 로직을 그대로 유지하면서 그 위에 투박한 국면 필터를 얹는 것입니다. 진입 타이밍을 잡는 척하지 않고, 단지 명백한 하락 추세 동안 보유하는 것을 피할 뿐입니다.

def apply_trend_gate(position: pd.Series, price: pd.Series, fast: int = 20, slow: int = 100):
    """Zero out the (already vol-targeted) position when the fast SMA is below
    the slow SMA. Both SMAs use only past prices, so no look-ahead is introduced.
    """
    fast_ma = price.rolling(fast).mean().shift(1)   # shift: known at prior close
    slow_ma = price.rolling(slow).mean().shift(1)
    gate = (fast_ma > slow_ma).astype(float)        # 1.0 in uptrend, 0.0 otherwise
    return position * gate.reindex(position.index).fillna(0.0)

추세 게이트는 하방에서 회전율을 줄여주지만(약세장에서 줄어드는 포지션을 계속 매매하지 않게 됩니다) 그 자체의 국면 위험을 더합니다. 횡보하는 혼조 시장에서는 휩소를 겪고, 전환점에서는 뒤처집니다. 이것이 도움이 되는지는 사이징 규칙 자체와 동일한 워크포워드, DM 검정의 엄밀함으로 답해야 하는 실증적 질문입니다. 추세 필터는 표본 내에서는 훌륭해 보이다가 표본 외에서는 사라져 버리는 바로 그런 종류의 추가 요소입니다.

DCC 공분산에 대한 포트폴리오 변동성 타겟팅. 여러 자산으로 구성된 포트폴리오의 경우, 스칼라 예측치 σ^t\hat\sigma_t는 포트폴리오 변동성 wΣtw\sqrt{w^\top \Sigma_t w}가 됩니다. 여기서 Σt\Sigma_tPart 3의 DCC-GARCH에서 나온 시변 공분산 행렬입니다. 기본 가중치 w0w_0(동일 가중, 시가총액, 또는 평균-분산 틸트)를 선택하고, Σt\Sigma_t 하에서 포트폴리오의 예측 변동성을 계산한 다음, 전체 가중치 벡터를 조정하여 포트폴리오 목표치에 도달시킵니다.

def portfolio_voltarget_weights(base_w, cov_forecast, target_vol_daily, w_gross_max=3.0):
    """Scale a base weight vector so forecast portfolio vol hits the target.
    base_w:        (n,) base allocation (need not sum to 1).
    cov_forecast:  (n, n) one-step-ahead covariance from DCC-GARCH (daily units).
    """
    base_w = np.asarray(base_w, dtype=float)
    port_var = float(base_w @ cov_forecast @ base_w)
    port_vol = np.sqrt(max(port_var, 1e-12))
    scale = min(target_vol_daily / port_vol, w_gross_max / np.abs(base_w).sum())
    return scale * base_w

이는 포트폴리오 구성 문헌으로 이어지는 자연스러운 다리입니다. 기본 가중치 w0w_0Markowitz 평균-분산이나 HRP/CVaR 같은 위험 기반 방법에서 나올 수 있으며, 변동성 타겟팅은 그 위에 집계 위험을 일정하게 조절하는 오버레이로서 자리 잡습니다. DCC 행렬이 중요한 이유는 폭락 시 상관관계가 급등하기 때문입니다(Part 3) — 조용한 시장에서는 분산되어 보이는 포트폴리오가, 정적 공분산이 암시하는 것보다 훨씬 높은 예측 변동성을 갖게 될 수 있으며, 바로 그것이 중요할 때 오버레이가 총 노출을 줄여 대응합니다.

항상 플롯해야 할 진단

요약 표만 믿지 마십시오. 어떤 변동성 타겟팅 전략이든, 어떤 샤프 숫자를 믿기 전에 세 가지를 플롯하고 눈으로 확인하십시오. 첫째, 전략의 실현 롤링 변동성 대 목표 라인 — 목표치에 밀착해야 합니다. 목표치 위로 체계적으로 벗어나면 예측이 낮게 편향되어 있다는 뜻입니다(비용이 큰 방향입니다). 둘째, 포지션/레버리지 시계열 — 상한이 발동하는 지점과 드로다운 직전의 레버리지 급등을 찾으십시오. 이는 국면 전환에 걸려든 예측치의 신호입니다. 셋째, 예측치 대 프록시 산점도(Mincer-Zarnowitz 그림) — 기울기가 1과 크게 다른 구름 모양은 QLIKE 평균이 숨길 수 있는 방식으로 예측치가 잘못 스케일되어 있음을 알려줍니다. 이 세 가지 플롯은 단일 통계량보다 훨씬 많은 버그와 자기기만을 잡아냅니다.

이 표는 모든 백테스트 표를 읽어야 하는 방식으로 읽으십시오. 무엇이 강건하고 무엇이 미미한지 보는 것입니다. 강건한 사실들은 눈에 확 띕니다. 모든 변동성 타겟팅 변형은 샤프에서, 그리고 더 극적으로는 드로다운과 실현 변동성 안정성에서 고정 명목 전략을 압도합니다 — 고정 명목 전략은 78%의 드로다운과 함께 연율화 68%의 변동성으로 운영되는데, 이는 단순히 투자 불가능한 수준입니다. 그리고 모든 타겟팅 방법은 20% 목표치에 가까운 실현 변동성을 전달합니다. 이것이 이 메커니즘이 작동한다는 약속 전체입니다. 미미한 사실은 예측기들 사이의 차이입니다. HAR가 GARCH를, GARCH가 EWMA를, EWMA가 롤링 RV를 근소하게 앞서지만, 그 격차는 작고 — 샤프 포인트의 10분의 1 정도 — Diebold-Mariano로 예측치를 검정하거나 수익률에 부트스트랩을 적용하면 유의성을 넘지 못하는 경우가 흔할 것입니다. 정교한 예측기와 소박한 예측기 사이의 이 작고 취약하며 국면 의존적인 격차야말로 이 시리즈 전체의 정직한 헤드라인입니다.

이것이 무엇을 사주는지 정직하게 밝히기

이 블로그에는 스스로를 속이지 않고 백테스트하는 것에 관한 컬렉션 전체가 있습니다. 그러니 이를 우리 자신의 결과에도 적용해봅시다. 조용히 여러분이 그러지 않기를 바라고만 있지 말고요.

변동성 타겟팅은 위험조정수익률과 드로다운을 개선합니다. 무에서 알파를 만들어내지는 않습니다. 표를 다시 보십시오. 타겟팅으로부터의 샤프 개선은 진짜이며 가질 가치가 있습니다 — 하지만 그것을 분해해보면 대부분은 고변동성 국면에 고정 포지션을 유지하지 않는 것에서 나오며, 이는 기계적으로 최악의 드로다운을 피하고 복리 경로를 안정화시킵니다. 전략은 여전히 BTC 롱입니다. 시장이 주지 않는 견해는 갖고 있지 않습니다. 만약 BTC가 여러분의 표본 기간 동안 음의 샤프를 가진다면, 변동성 타겟팅은 여러분에게 덜 나쁜 음의 샤프를 안겨줄 것이지, 양의 샤프를 주지는 않을 것입니다. 이는 수익 분포의 형태를 바꿉니다 — 더 얇은 꼬리, 더 안정적인 변동성, 더 나은 기하 복리 — 하지만 원초적인 방향성 우위는 기초 자산의 롱 포지션이 가진 것 그대로입니다. 아름다운 자산 곡선에 속아 위험 관리를 찾아놓고 알파를 발견했다고 믿지 마십시오. Moreira-Muir는 변동성 관리를 통해 주식 팩터에서 진정한 알파를 발견했지만, 그 결과는 팩터의 시변 위험-수익 상충 관계에 관한 것이며, 다른 표본 기간의 단일 크립토 자산에 자동으로 이전되지는 않습니다.

EWMA 대비 GARCH의 예측 품질 우위는 종종 작고 국면에 의존적입니다. 이것이 Part 1-3의 불편한 대가입니다. 여러분은 점점 더 정교한 모델을 구축했습니다 — 레버리지 항, Student-t 꼬리, 동적 상관관계 — 하지만 각각이 소박한 EWMA 대비 변동성 타겟팅 손익에 기여하는 한계적 공헌은 종종 노이즈 대역 안에 있습니다. GARCH의 우위(충격 이후 평균회귀)는 주로 특정 국면에서 나타납니다. 급격한 급등 후 정상화되는 경우입니다. 지속적인 추세나 끈질긴 고변동성 국면에서는 EWMA와 거의 차이가 없습니다. 이것이 GARCH를 쓸모없게 만들지는 않습니다 — 평균회귀 구조, 해석 가능한 파라미터, 앞으로의 경로를 시뮬레이션하고 예측치에 대해 옵션 가격을 매길 수 있는 능력 모두 EWMA에는 없는 가치를 가지고 있습니다 — 하지만 여러분의 유일한 용도가 사이징이라면, 복잡성 비용을 지불하기 전에 DM 검정을 실행하고, 국면 감지가 다른 각도에서 동일한 것을 말하고 있음을 아십시오. 승리하는 모델은 국면에 달려 있습니다.

백테스트 샤프는 실거래 샤프의 상한이며, 변동성 타겟팅은 그 격차를 더 벌립니다. 전략이 회전율이 높고 레버리지로 스케일되기 때문에, 소박한 백테스트가 생략하는 마찰에 유별나게 민감합니다. 실제 체결가는 사이징에 사용한 종가보다 나쁘고, 레버리지 퍼프 포지션에는 자금조달 비용이 지속적으로 누적되며, 레버리지 상한은 단순한 w * return이 무시하는 증거금 및 청산 메커니즘과 상호작용합니다. 이 모든 것이 실거래를 백테스트보다 나쁘게 만듭니다. 우리는 이 격차를 백테스트-실거래 정합성에서 체계적으로 다뤘습니다. 변동성 타겟팅에 특화해서는, 보수적인 비용, 현실적인(낮은) 레버리지 상한을 사용하고, 시그널을 계산한 종가가 아니라 다음 봉의 시가에서 체결함으로써 이를 대비하십시오.

변동성 위험 프리미엄에 대한 여담. 위의 모든 것은 실현 변동성을 예측합니다. 이와 병행하는 거래 가능한 대상이 있습니다. 옵션에 가격이 매겨지는 내재 변동성인데, 이는 평균적으로 이후 실현 변동성보다 높게 자리 잡습니다 — 변동성 위험 프리미엄, 즉 변동성 급등 위험을 부담하는 것에 대한 보상입니다. 그 격차 자체가 수익의 원천입니다(분산을 매도하면 이를 수확하고, 매수하면 꼬리 위험을 헤지합니다). 그리고 이는 변동성 타겟팅과는 진정으로 다른 게임입니다. 변동성의 예측을 사용하는 것이 아니라 변동성의 가격에 베팅하는 것입니다. 여기서는 이를 다루지 않지만, 그 메커니즘은 Black-Scholes 옵션 가격 결정의 가격 결정 모델에서 시작하며, 좋은 실현 변동성 예측(Part 1-2)이 바로 내재 변동성이 비싼지 싼지를 판단하는 데 필요한 입력값입니다. GARCH 예측치를 옵션 시장의 내재 변동성과 비교하는 것은 이 시리즈에서 구축한 모든 것의 가장 정직한 용도 중 하나입니다.

실용적 고려사항

작동하는 변동성 타겟팅과 취약한 변동성 타겟팅을 가르는 잡다한 항목들입니다.

  • 올바른 기간에 맞춰 추정하십시오. 하루 동안 보유되는 포지션을 사이징한다면 하루 변동성을 예측하십시오. 주 단위로 리밸런싱한다면 주간 변동성을 예측(및 타겟팅)하거나, 일간 GARCH 예측치를 해당 기간에 걸쳐 집계하십시오 — 다단계 GARCH 예측은 σˉ2\bar\sigma^2을 향해 평균회귀하는데, 소박한 "h일간\sqrt{h}\cdot\text{일간}" 스케일링은 이를 무시합니다. Part 1이 다단계 GARCH 예측을 다뤘습니다.
  • 24/7 시장에서의 연율화. 크립토는 주말이나 공휴일 없이 1년에 365일 거래되므로, 주식의 252\sqrt{252}가 아니라 365\sqrt{365}로 일간 변동성을 연율화하십시오. 이를 틀리면 목표치가 약 20% 조용히 잘못 스케일됩니다.
  • 분모는 공분산 행렬이 될 수 있습니다. 다중 자산 포트폴리오의 경우, 스칼라 σ^t\hat\sigma_tPart 3의 DCC-GARCH로부터 나온 포트폴리오 변동성 wΣtw\sqrt{w^\top \Sigma_t w}로 대체하고, 전체 가중치 벡터를 조정하여 포트폴리오 목표 변동성에 맞추십시오. 이는 변동성 타겟팅을 평균-분산 사이징(크립토를 위한 Markowitz)과 위험 기반 배분(HRP와 CVaR 파이프라인)에 연결합니다 — 변동성 타겟팅은 포트폴리오 위험 예산에 맞춰 스케일링하는 것의 단일 자산 특수 사례입니다.
  • 변동성 타겟팅은 미묘한 방식으로 경기순응적입니다. 모두가 동일한 1/σ1/\sigma 규칙을 실행하면, 변동성 급등이 동기화된 디레버리징을 강제하고, 이는 가격을 끌어내리며, 그것이 실현 변동성을 높이고, 다시 더 많은 디레버리징을 강제합니다. 이 피드백(2018년 "볼마게돈"과 다양한 크립토 디레버리징 캐스케이드에서 잘 문서화되었습니다)은 많은 참여자가 이 규칙을 사용할 때 정확히 그 규칙이 덜 잘 작동한다는 것을 의미합니다. 이것이 규칙을 포기할 이유는 아니지만, 레버리지에 상한을 두고 변동성 급등 중의 체결이 조용한 시장의 체결과 비슷할 것이라고 가정하지 말아야 할 이유입니다.
  • 예측치에 하한을 두고 클리핑하십시오. 0에 가까운 예측 변동성은 무한한 레버리지를 만들어냅니다. σ^t\hat\sigma_t에 항상 합리적인 최솟값 하한을 두고 포지션에 상한을 두며, 각각이 얼마나 자주 발동하는지 기록하십시오 — 상한이 대부분의 시간 동안 발동한다면, 목표치가 그 자산에 비해 지나치게 공격적이라는 뜻입니다.

요약

  • 변동성 예측은 결정을 바꾸기 전까지는 가치가 없습니다. 변동성 타겟팅 — 노출을 wt=σtarget/σ^tw_t = \sigma_{\text{target}}/\hat\sigma_t(상한 적용)로 사이징하는 것 — 은 예측 가치를 검증하는 가장 깔끔한 방법입니다. 예측 품질이 직접적으로 더 평탄한 실현 변동성 프로파일과 더 높은 샤프로 매핑되기 때문입니다.
  • 변동성 타겟팅은 위험조정수익률을 높이며, 특히 드로다운을 통제합니다. 변동성은 예측 가능하지만(군집을 이룹니다) 방향은 그렇지 않기 때문이며, 샤프 비율이 규칙이 자동으로 비중을 줄이는 고변동성 국면에서 하락하기 때문입니다. 이는 기대 수익이 변동성에 비례한다는 가정 하의 Kelly 사이징입니다.
  • GARCH를 강력한 기준선들과 정직하게 벤치마킹하십시오. 롤링 실현 변동성, EWMA/RiskMetrics(λ=0.94\lambda=0.94, 자유 파라미터가 없는 IGARCH), 그리고 인트라데이 실현 분산 프록시에 대한 HAR-RV입니다. EWMA와 HAR는 이기기 어렵습니다.
  • 진짜 변동성은 관측할 수 없으므로, 프록시 노이즈에 강건한 손실 함수를 사용하여 프록시(r2r^2 또는 훨씬 더 나은 RVRV)에 대해 평가하십시오. MSE보다 QLIKE를 선호하십시오. 과소 예측(비용이 큰 오류)을 더 크게 벌하며 스케일 불변이기 때문에, 소수의 고변동성 날들에 좌우되지 않습니다. Mincer-Zarnowitz로 편향을 진단하고, Diebold-Mariano 검정으로 한 예측치의 우위가 진짜인지 노이즈인지 판단하십시오.
  • 워크포워드이며 비용을 반영한 백테스트에서, 변동성 타겟팅은 샤프와 드로다운에서 고정 명목을 안정적으로 이깁니다. 네 예측기는 서로 가깝게 군집합니다 — GARCH가 EWMA 대비 갖는 우위는 작고, 국면 의존적이며, 종종 통계적으로 유의하지 않습니다. 평균 손실뿐 아니라 DM 검정도 보고하십시오.
  • 정직해집시다. 변동성 타겟팅은 위험 관리이지, 알파가 아닙니다. 이미 가지고 있던 방향성 베팅의 수익 분포 형태를 바꿀 뿐, 무에서 우위를 만들어내지 않습니다. 그리고 회전율이 높고 레버리지로 스케일되기 때문에, 실거래 결과는 평소보다 백테스트에 더 크게 뒤처집니다.

참고문헌:

  • Patton, A. J. (2011). Volatility forecast comparison using imperfect volatility proxies. Journal of Econometrics, 160(1), 246-256. DOI
  • Corsi, F. (2009). A simple approximate long-memory model of realized volatility. Journal of Financial Econometrics, 7(2), 174-196. DOI
  • Diebold, F. X., & Mariano, R. S. (1995). Comparing predictive accuracy. Journal of Business & Economic Statistics, 13(3), 253-263. DOI
  • Mincer, J., & Zarnowitz, V. (1969). The evaluation of economic forecasts. In Economic Forecasts and Expectations, NBER.
  • Moreira, A., & Muir, T. (2017). Volatility-managed portfolios. Journal of Finance, 72(4), 1611-1644. DOI
  • J.P. Morgan / Reuters (1996). RiskMetrics Technical Document, 4th ed.
  • Bollerslev, T. (1986). Generalized autoregressive conditional heteroskedasticity. Journal of Econometrics, 31(3), 307-327. DOI
  • Glosten, L. R., Jagannathan, R., & Runkle, D. E. (1993). On the relation between the expected value and the volatility of the nominal excess return on stocks. Journal of Finance, 48(5), 1779-1801. DOI
  • Harvey, D., Leybourne, S., & Newbold, P. (1997). Testing the equality of prediction mean squared errors. International Journal of Forecasting, 13(2), 281-291. DOI
blog.disclaimer

MarketMaker.cc Team

퀀트 리서치 및 전략

Telegram에서 토론하기
Newsletter

시장에서 앞서 나가세요

뉴스레터를 구독하여 독점적인 AI 트레이딩 통찰력, 시장 분석 및 플랫폼 업데이트를 받아보세요.

귀하의 개인정보를 존중합니다. 언제든지 구독을 취소할 수 있습니다.