← 기사 목록으로
May 25, 2026
5분 소요

내부 알고리즘 분석: HRP + 롱/숏 + Hull-White를 사용한 CVaR

내부 알고리즘 분석: HRP + 롱/숏 + Hull-White를 사용한 CVaR
#포트폴리오 최적화
#HRP
#계층적 위험 패리티
#CVaR
#Hull-White
#EWMA
#롱/숏
#위험 관리
#Rust
#퀀트 금융

«12가지 포트폴리오 최적화 알고리즘 비교» 개요에서 우리는 12가지 자산 배분 방법을 나란히 비교했습니다. 그 중 11가지는 교과서적인 고전입니다. 12번째인 파이프라인은 우리의 알고리즘이며, 해당 게시물에서 정확히 한 항목으로 설명되었습니다. 이 글은 파이프라인의 심층 분석입니다. 파이프라인의 내부 구성, 각 공식의 출처, 그리고 사양이 Rust 코드로 어떻게 변환되는지에 대해 다룹니다.

파이프라인은 가중치를 계산하는 새로운 방법을 발명하지 않습니다. 가장 견고하다고 알려진 방법인 **계층적 위험 패리티(HRP)**를 가져와 실제 거래 계좌에 필요하지만 일반 HRP에는 없는 두 가지 계층으로 감쌉니다. 바로 방향(전략 신호에 따른 롱/숏)과 엄격한 위험 예산(현재 변동성 체제에 맞춰 조정된 CVaR)입니다. 이는 네 가지 단계를 구성합니다.

네 가지 단계

가격  I  로그 수익률  II  HRP 가중치  III  롱/숏  IV  CVaR 예산\text{가격} \;\xrightarrow{\text{I}}\; \text{로그 수익률} \;\xrightarrow{\text{II}}\; \text{HRP 가중치} \;\xrightarrow{\text{III}}\; \text{롱/숏} \;\xrightarrow{\text{IV}}\; \text{CVaR 예산}
  • I — 모든 자산의 로그 수익률.
  • II — HRP에서 얻은 기본 가중치.
  • III — 에이전트 신호에서 얻은 롱/숏 분할, 신뢰도에 따라 위험 분담률 설정.
  • IV — Hull-White 변동성을 사용한 CVaR 보정; 초과 위험은 현금으로 전환.

순서대로 살펴보겠습니다.

1단계. 로그 수익률

모든 것은 가격에서 로그 수익률로의 전환에서 시작됩니다.

ri,t=ln ⁣(Si,tSi,t1)r_{i,t} = \ln\!\left(\frac{S_{i,t}}{S_{i,t-1}}\right)

여기서 ii는 자산이고 tt는 시간 단계입니다. 로그 수익률은 시간이 지남에 따라 합산되며, 단순 퍼센트 변화보다 더 대칭적입니다. 이는 모든 공분산 계산의 표준 입력입니다.

2단계. HRP를 기반으로

2016년 Marcos López de Prado가 제안한 HRP는 평균-분산 최적화의 핵심 문제인 조건이 좋지 않은 공분산 행렬을 역전시키는 것을 피합니다. HRP는 공분산 행렬을 전혀 역전시키지 않습니다. 대신 상관관계의 구조를 활용합니다.

공분산 및 상관관계

수익률로부터 공분산 행렬 Σ\Sigma를 구축하고 이를 상관관계 행렬 CC로 정규화합니다.

Σi,j=Cov(ri,rj),Ci,j=ρi,j=Cov(ri,rj)σiσj\Sigma_{i,j} = \mathrm{Cov}(r_i, r_j), \qquad C_{i,j} = \rho_{i,j} = \frac{\mathrm{Cov}(r_i, r_j)}{\sigma_i \sigma_j}

거리 행렬

상관관계를 거리 측정으로 변환하여 강하게 상관된 자산이 "가깝게" 위치하도록 합니다.

di,j=1ρi,j2d_{i,j} = \sqrt{\frac{1 - \rho_{i,j}}{2}}

ρi,j\rho_{i,j}가 1에 가까울수록 di,jd_{i,j}는 0에 가까워지며, 자산들이 클러스터를 공유할 가능성이 높아집니다.

덴드로그램 및 리프 순서

거리 행렬로부터 **평균 연결(average linkage)**을 통해 클러스터 계층 구조를 구축하고 리프 순서 π=(π1,,πN)\pi = (\pi_1, \ldots, \pi_N)를 읽어냅니다. 이는 유사한 자산들이 인접하게 위치하는 자산들의 순열입니다.

선택적 단계: 최적의 클러스터 수는 실루엣 계수 si=biaimax(bi,ai)s_i = \dfrac{b_i - a_i}{\max(b_i, a_i)}로 선택할 수 있습니다. 여기서 aia_i는 클러스터 내 평균 거리이고 bib_i는 가장 가까운 이웃 클러스터까지의 평균 거리입니다. 기본 단계에서는 필요하지 않습니다. 재귀적 이분법은 이미 계층 구조를 따릅니다.

준대각화

Σ\Sigma의 행과 열을 π\pi로 순열하여 대각선을 따라 큰 값들을 모읍니다.

Σi,jq=Σπi,πj\Sigma^{q}_{i,j} = \Sigma_{\pi_i, \pi_j}

재귀적 이분법

그 다음 재귀는 하향식으로 실행됩니다. 각 단계에서 클러스터는 LLRR로 절반으로 분할되고, 자본은 두 절반 사이에 분산에 반비례하여 할당됩니다.

wL=1/σL21σL2+1σR2,wR=1wLw_L = \frac{1/\sigma_L^2}{\dfrac{1}{\sigma_L^2} + \dfrac{1}{\sigma_R^2}}, \qquad w_R = 1 - w_L

클러스터의 분산은 해당 공분산 하위 블록에서 σC2=1m2i,jCΣi,jq\sigma_C^2 = \tfrac{1}{m^2}\sum_{i,j \in C}\Sigma^{q}_{i,j}로 계산됩니다. 각 노드가 단일 자산을 가질 때까지 하향식으로 진행됩니다. 가중치는 롱-온리(long-only)이며, 음수가 아니고, 합이 1.0입니다.

우리의 구현에서 이는 hrp_from_cov(cov) -> Vec<f64> 함수입니다. 상관관계 → 거리 → 평균 연결 → 리프 순서 → 준대각화 → 재귀적 이분법. 파이프라인은 이를 기본으로 호출하며, 신호가 없는 경우의 공개 optimize() 함수이기도 합니다.

3단계. 롱/숏 오버레이

일반 HRP는 "매수 전용" 포트폴리오입니다. 그러나 전략은 종종 얼마나 많이 뿐만 아니라 어떤 방향으로도 지시합니다. 3단계는 에이전트로부터 자산별 신호(Long/Short)를 받아 두 개의 하위 포트폴리오를 구축합니다.

  1. 자산은 신호에 따라 롱 바스켓과 숏 바스켓으로 나뉩니다.
  2. 바스켓 내에서 가중치는 동일한 HRP(해당 자산의 공분산 하위 블록에 대해)로 계산되며, 각 바스켓당 합이 1이 됩니다.
  3. 에이전트가 신뢰도 pip_i도 발행하는 경우, 양측 간의 위험 분담률은 총 신뢰도에 의해 설정됩니다.

ξL=iLpi,ξS=iSpi,λL=ξLξL+ξS,λS=ξSξL+ξS\xi_L = \sum_{i \in L} p_i, \quad \xi_S = \sum_{i \in S} p_i, \qquad \lambda_L = \frac{\xi_L}{\xi_L + \xi_S}, \quad \lambda_S = \frac{\xi_S}{\xi_L + \xi_S}

신뢰도가 없는 경우, 분담률은 각 바스켓의 자산 수로 돌아갑니다. 최종 부호 있는 가중치는 롱의 경우 wi=λLwiHRPw_i = \lambda_L \cdot w_i^{\text{HRP}}이고 숏의 경우 wi=λSwiHRPw_i = -\lambda_S \cdot w_i^{\text{HRP}}이며, 그 후 전체 총 노출은 1로 정규화됩니다.

코드에 대한 솔직한 언급. 원래 사양에는 보정 계수 αL=λL/σL\alpha_L = \sqrt{\lambda_L}/\sigma_L, αS=λS/σS\alpha_S = \sqrt{\lambda_S}/\sigma_S가 포함되어 있지만, "이 단계가 정말 필요한가?"라는 표시도 있습니다. 구현에서는 이를 적용하지 않습니다. 양측은 위험 분담률 λ\lambda에 의해 직접 결합되며, 이는 총 노출을 정확히 1로 유지하고 숨겨진 레버리지를 생성하지 않습니다. 이는 사양의 의도적인 단순화이며, 간과가 아닙니다.

4단계. Hull-White 조정을 사용한 CVaR

HRP는 위험을 구조적으로 균형화하지만, 금전적 측면에서 절대적인 위험 수준에 대해서는 아무것도 알지 못합니다. 최종 단계는 꼬리 위험에 대한 엄격한 상한선을 설정하고, 시장 체제 변화에 민감하게 만듭니다.

포트폴리오 수익률 및 EWMA 변동성

먼저 가중치를 포트폴리오 수익률로 통합하고 EWMA를 사용하여 조건부 변동성을 추정합니다.

rp,t=i=1nwiri,t,σp,t2=λσp,t12+(1λ)rp,t12r_{p,t} = \sum_{i=1}^{n} w_i\, r_{i,t}, \qquad \sigma_{p,t}^2 = \lambda\, \sigma_{p,t-1}^2 + (1 - \lambda)\, r_{p,t-1}^2

여기서 λ=0.94\lambda = 0.94 (고전적인 RiskMetrics 값)입니다. EWMA는 전체 역사에 걸쳐 평균된 변동성보다는 "오늘의" 변동성을 제공합니다.

Hull-White 재조정

핵심 아이디어: 과거 수익률은 있는 그대로 받아들일 수 없습니다. 이는 다른 변동성 하에서 발생했기 때문입니다. Hull-White 방법은 각 과거 수익률을 현재 수준으로 재조정합니다.

r~p,s=σp,t+1σp,srp,s,s=tN+1,,t\widetilde{r}_{p,s} = \frac{\sigma_{p,t+1}}{\sigma_{p,s}}\, r_{p,s}, \qquad s = t - N + 1, \ldots, t

평온한 달은 "늘어나고", 격동적인 달은 "압축"되어 분포가 현재 체제로 맞춰집니다.

VaR 및 CVaR

재조정된 분포에서 손실 분위수와 꼬리 부분의 평균 손실을 취합니다.

VaRαHW=q1α(r~p)VaR_\alpha^{HW} = -q_{1-\alpha}(\widetilde{r}_p)

CVaRαHW=E ⁣[r~pr~pq1α(r~p)]CVaR_\alpha^{HW} = -\mathbb{E}\!\left[\widetilde{r}_p \mid \widetilde{r}_p \le q_{1-\alpha}(\widetilde{r}_p)\right]

CVaR (일명 Expected Shortfall)은 "일반적인 나쁜 날이 얼마나 나쁜가"가 아니라 "가장 나쁜 α\alpha 퍼센트에서 평균적으로 얼마나 나쁜가"에 답합니다. 따라서 꼬리의 가장자리뿐만 아니라 꼬리의 두께를 봅니다.

위험 예산 및 현금

CVaR이 허용 가능한 임계값을 초과하면 모든 위험 포지션은 단일 계수로 축소되고, 확보된 자본은 현금으로 이동합니다.

winew=γwi,γ=CVaRmaxCVaRαHW,wcash=1i=1nwineww_i^{new} = \gamma\, w_i, \quad \gamma = \frac{CVaR_{\max}}{CVaR_\alpha^{HW}}, \qquad w_{cash} = 1 - \sum_{i=1}^{n} |w_i^{new}|

따라서 포트폴리오는 꼬리 위험이 증가할 때 위험을 줄이고, 진정될 때 시장에 재진입합니다.

사양에서 코드로

전체 알고리즘은 단일 Rust 크레이트인 portfolio-pipeline에 있으며, 워크스페이스의 통일된 계약을 따릅니다.

pub fn optimize(prices: &[Vec<f64>]) -> Vec<f64>

이는 롱-온리(long-only) 투영(신호 없는 1, 2, 4단계)입니다. 다른 11가지 알고리즘과 정확히 동일한 prices -> weights 인터페이스를 가지므로, 파이프라인은 이들 중 어느 것에든 드롭인 대체품으로 사용할 수 있습니다. 모든 단계를 포함하는 전체 버전은 별도의 함수입니다.

pub fn run(
    prices: &[Vec<f64>],
    signals: Option<&[Side]>,      // 자산별 롱/숏
    confidence: Option<&[f64]>,    // 에이전트 신뢰도 → 위험 분담률 λ
    cfg: &PipelineConfig,          // CVaR / Hull-White 매개변수
) -> PipelineResult                // 부호 있는 가중치 + 현금 + cvar + σ

오버레이 기본값: 꼬리 cvar_alpha = 0.05, 예산 cvar_max = 0.05, EWMA ewma_lambda = 0.94, Hull-White 윈도우 hw_window = 0 (전체 역사). 구현은 외부 종속성이 없으며 의도적으로 방어적입니다. 짧은 역사(4개 미만의 가격 포인트)에서는 동일한 가중치를 반환하고, CVaR 오버레이는 8개 이상의 수익률 관측치가 있을 때만 작동합니다. 그렇지 않으면 꼬리를 추정할 것이 없습니다.

Rust를 사용하는 이유: 백테스트와 프로덕션 모두에 대해 하나의 결정론적 코드베이스를 사용하여 "연구는 Python, 프로덕션은 다른 언어"와 같은 이탈을 방지하고, 비교 백엔드를 통해 단일 요청으로 12가지 알고리즘을 모두 실행할 수 있을 만큼 빠릅니다.

시간 비용

"충분히 빠르다"는 것은 얼마나 빠르다는 것일까요? HRP 코어(로그 수익률 → 공분산 → 평균 연결 → 준대각화 → 재귀적 가중치)를 독립형 벤치마크로 분리하여, 정확히 동일한 수학 연산을 일곱 가지 언어 — C, C++, Rust, Zig, Python, Node.js, Bun — 에서 동일한 조건으로 실행했습니다. Apple Silicon, 단일 스레드, 자산당 365일 일일 관측치, 합성 가격, 자산 수 NN은 10에서 10,000까지입니다.

복잡도에 대한 한마디. 이것이 전체 형태를 결정하기 때문입니다. 평균 연결의 교과서적 버전은 병합할 때마다 가장 가까운 쌍을 찾기 위해 전체 거리 행렬을 다시 스캔합니다. 이는 O(N3)O(N^3)이며 수천 개의 자산에서 병목이 됩니다. 대신 이 벤치마크는 SciPy의 linkage(method='average') 뒤에 있는 것과 동일한 O(N2)O(N^2) 최근접 이웃 체인(nearest-neighbour-chain) 알고리즘(Müllner 2011)을 사용합니다. 이를 적용하면 클러스터링은 더 이상 지배적인 단계가 아닙니다. N=2000N = 2000에서 ~0.5초 통과 중 ~15ms에 불과합니다. 이제 비용은 공분산 행렬, O(N2T)O(N^2 \cdot T) 에 의해 지배되며, 이는 어떤 HRP 계열 방법도 피할 수 없는 유일한 단계입니다.

실행 결과가 보여주는 것(언어별 전체 표와 한 번의 명령으로 재현하는 스크립트는 프로젝트 저장소에 있습니다):

  • 현실적인 포트폴리오에서는 비용이 거의 들지 않습니다. 암호화폐 바스켓은 수십 개의 자산으로 구성되며, 100개를 넘는 경우는 드뭅니다. N100N \le 100에서 전체 HRP 통과는 Node에서도 한 자릿수 밀리초, Rust/C에서는 마이크로초입니다. 매 틱마다 가중치를 재계산하는 것은 문제가 되지 않습니다.
  • Rust는 C의 ~1.0–1.3배 이내입니다. 동일한 크기이며 둘 다 컴파일되고, NN이 수천에 도달하면 사실상 동등합니다. C는 순수 산술에서 약간 더 빠르지만, Rust는 가비지 컬렉터나 UB 없이 동일한 예측 가능성을 제공합니다.
  • 수천 개의 자산까지 확장됩니다. O(N2)O(N^2) 연결을 사용하면 컴파일된 언어에서 전체 통과는 N=2000N = 2000에서 ~0.5초, N=5000N = 5000에서 몇 초입니다. 해석형인 Node조차도 N=2000N = 2000을 2초 미만으로 처리합니다. 이제 천장을 결정하는 것은 클러스터링이 아니라 공분산 단계입니다.

실용적인 결론: 우리의 포트폴리오 크기에서 Rust를 선택하는 것은 "C를 이기는 것"(여기서는 C가 약간 더 빠름)에 관한 것이 아닙니다. 이는 연구 및 생산을 위한 하나의 결정론적 코드베이스, GC 일시 중지 없음, 그리고 수년간의 성능 여유에 관한 것입니다. 결과와 재현 스크립트를 포함한 전체 일곱 가지 언어 벤치마크는 프로젝트 저장소에서 공개되어 있습니다.

파이프라인이 12가지 알고리즘 중 차지하는 위치

의도적으로 조작된 단일 바스켓에 대한 비교에서 파이프라인은 HRP처럼 작동했습니다. 왜냐하면 롱-온리 optimize() 진입점을 통해 CVaR 오버레이가 있는 HRP 이기 때문입니다. 파이프라인의 방향성 메커니즘은 전략 신호를 제공할 때만 활성화됩니다. 이것이 핵심입니다. 파이프라인은 "백테스팅 가중치를 위한 또 다른 최적화 도구"가 아니라 전략 신호와 실제 주문 사이의 실행 계층입니다. 이는 매수/매도 호출을 받아 각 측면 내에서 HRP로 자본을 배분하고, 신뢰도에 따라 측면의 균형을 맞추며, 꼬리 위험을 설정된 예산으로 줄입니다.

전체 맥락, 즉 다른 11가지 방법이 무엇이며 어떻게 다른지에 대해서는 «12가지 포트폴리오 최적화 알고리즘 비교» 개요를 참조하십시오. 그리고 portfolio-optimizer.marketmaker.cc에서 이 모든 것을 직접 시도해 볼 수 있습니다.

참고 문헌

  1. López de Prado, M. (2016). Building Diversified Portfolios that Outperform Out of Sample. The Journal of Portfolio Management.
  2. López de Prado, M. (2018). Advances in Financial Machine Learning. Wiley.
  3. Hull, J., & White, A. (1998). Incorporating Volatility Updating into the Historical Simulation Method for Value at Risk. Journal of Risk.
  4. Rockafellar, R. T., & Uryasev, S. (2000). Optimization of Conditional Value-at-Risk. Journal of Risk.
  5. RiskMetrics Group (1996). RiskMetrics — Technical Document. J.P. Morgan.
  6. Marketmaker.cc: marketmaker.cc

인용

@article{soloviov2026pipeline,
  author = {Soloviov, Eugen and Zhuravleva, Marina and Kiselev, Kirill},
  title = {Inside Our House Algorithm: HRP + Long/Short + CVaR with Hull-White Adjustment},
  year = {2026},
  url = {https://marketmaker.cc/ko/blog/post/portfolio-pipeline-hrp-cvar},
  description = {A deep dive into Pipeline, a composite portfolio allocation algorithm built on Hierarchical Risk Parity with a signal-driven long/short overlay and a Hull-White CVaR risk-budget correction, with the full specification and its Rust implementation.}
}
blog.disclaimer

Authors

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Marina Zhuravleva
Marina Zhuravleva

Financial mathematics

Fifth-year student at Bauman Moscow State Technical University (Automatic Control Systems), specializing in financial mathematics. Background in calibrating stochastic-volatility (Heston) and local-volatility (Dupire) models, fair pricing of options including exotics via both Monte-Carlo and analytic formulas, hedging-error reduction, and exposure to LSV models.

Kirill Kiselev
Kirill Kiselev

Portfolio optimization

Fourth-year student at the Faculty of Mechanics and Mathematics, Novosibirsk State University (NSU); thesis on Heston-model calibration and delta-hedging within the same model. Works on portfolio optimization.

Newsletter

시장에서 앞서 나가세요

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

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