
고정 호라이즌(Fixed Horizon) 라벨이 좋지 않은 이유 — 트리플 배리어(Triple Barrier)법이라는 선택지
요약
금융 데이터 학습 시 발생하는 고정 호라이즌(Fixed Horizon) 라벨링의 구조적 결함을 분석하고, 이를 해결하기 위한 트리플 배리어(Triple Barrier)법을 소개합니다. 실제 트레이딩 규칙과 일치하는 라벨 설계와 변동성을 반영한 동적 배리어 설정의 중요성을 강조합니다.
핵심 포인트
- 고정 호라이즌 라벨은 중간 손절/익절 과정을 무시하는 한계가 있음
- 트리플 배리어법은 익절, 손절, 시간 배리어를 통해 실제 매매 문맥을 반영함
- 시장 변동성에 따라 배리어 폭을 동적으로 조절하는 것이 효과적임
- 모델이 학습하는 대상과 실제 운용 규칙의 일치성이 핵심임
이 기사는 Zenn에 게시한 내용을 재게시한 것입니다. 초출: 고정 호라이즌(Fixed Horizon) 라벨이 좋지 않은 이유 — 트리플 배리어(Triple Barrier)법이라는 선택지
이전에 검증이 거짓말을 하는 패턴에 대해 연재를 작성했습니다. 그 연재는 "검증을 어떻게 망가뜨리지 않을 것인가"가 테마였지만, 이번에는 그 한 단계 전의 이야기입니다. 애초에 무엇을 예측하게 할 것인가 — 라벨(Label) 설계에 대해 쓰겠습니다.
라벨은 검증이 아무리 정확하더라도, 설계 자체가 나쁘면 의미 있는 모델이 되지 않습니다. 그리고 이 설계는 놀라울 정도로 대충 이루어지기 쉽습니다.
가장 소박한 라벨은 다음과 같은 형태입니다.
# 「이후 20개 봉 뒤의 가격이 지금보다 올라가 있는가」를 예측한다
df["label"] = (df["close"].shift(-20) > df["close"]).astype(int)
심플하고 이해하기 쉽습니다. 하지만 여기에는 구조적인 약점이 두 가지 있습니다.
고정 호라이즌(Fixed Horizon) 라벨은 "20개 봉 뒤에 플러스인가"만을 보고 있습니다. 그 도중에 미실현 손실이 실제 손절 폭을 초과하여 망가졌더라도, 20개 봉 뒤에 우연히 돌아온다면 "승리"로 라벨링됩니다. 반대로, 초반에 크게 익절 라인에 도달했더라도 20개 봉 뒤에 반락하면 "패배"가 됩니다.
이는 실제 트레이딩 규칙(익절·손절)과 라벨의 정의가 일치하지 않습니다. 모델은 당신이 실제로는 취하지 않을 동작("도중에 무슨 일이 있어도 20개 봉까지 계속 보유한다")을 학습하게 됩니다.
"20개 봉"이라는 숫자에 근거가 있을까요? 많은 경우, 대충 정한 값입니다. 종목이나 변동성(Volatility)이 바뀌면 최적의 호라이즌(Horizon)도 바뀔 텐데, 고정값은 시장의 상태를 무시합니다. 변동성이 높은 날 20개 봉 동안 움직이는 가격 폭과, 조용한 날 20개 봉 동안 움직이는 가격 폭은 완전히 다른 의미를 갖습니다.
이 두 가지 약점에 대한 비교적 자주 사용되는 해법이 트리플 배리어(Triple Barrier)법입니다. López de Prado가 체계화한 수법으로 알려져 있습니다.
발상은 심플합니다. 각 진입 후보점에 대해 3개의 배리어(Barrier)를 긋습니다.
상단 배리어 (익절 라인) -
하단 배리어 (손절 라인) -
시간 배리어 (보유 기한)
그리고 어느 배리어에 가장 먼저 닿았는가로 라벨을 결정합니다.
import pandas as pd
import numpy as np
def triple_barrier_label(
...
이를 통해 얻을 수 있는 라벨은 실제 트레이딩 규칙(익절 폭·손절 폭·보유 기한)과 정의가 일치합니다. "20개 봉 뒤에 플러스인가"가 아니라, "익절 라인과 손절 라인 중 어느 쪽에 먼저 닿았는가"를 직접 라벨화하고 있으므로, 모델이 학습하는 대상과 실제 운용에서 모델이 사용되는 문맥이 어긋나지 않습니다.
고정 퍼센티지(Fixed Percentage) 배리어에도 고정 호라이즌과 같은 약점이 남습니다. "상하 2%"를 모든 종목·모든 기간에 고정하면 변동성의 높고 낮음을 무시하게 됩니다.
개선책은 배리어 폭을 그 시점의 변동성에 연동시키는 것입니다.
def dynamic_barriers(prices: pd.Series, entry_idx: int, vol_window: int = 20, barrier_mult: float = 2.0):
"""최근의 변동성에 따라 배리어 폭을 결정한다"""
returns = prices.pct_change()
...
변동성이 높은 국면에서는 배리어를 넓게, 조용한 국면에서는 좁게 가져감으로써 "어떤 시장 상황에서도 유사한 '의미 있는 가격 폭'을 포착하는" 라벨이 됩니다.
트리플 배리어법을 포함하여, 라벨은 흔히 불균형해집니다. "시간 초과(0 부근)"가 많고, 명확한 익절·손절에 도달하는 케이스가 적은 분포가 되기 쉽습니다.
대처 방법은 몇 가지 있습니다.
# 시간 배리어로 결판이 난 샘플을 학습 대상에서 제외
labeled = df[df["barrier_type"] != "time"]
가장 심플한 방법입니다. 다만 샘플 수가 크게 줄어들기 때문에 데이터량이 적은 경우에는 주의가 필요합니다.
from sklearn.utils.class_weight import compute_class_weight
classes = np.unique(y_train)
weights = compute_class_weight("balanced", classes=classes, y=y_train)
...
데이터를 제외하지 않고, 학습 시 소수 클래스(minority class)의 가중치를 높이는 방법입니다. 데이터를 버리지 않는다는 장점이 있지만, 소수 클래스에 대한 과적합 (overfitting)에는 주의해야 합니다.
이것은 López de Prado가 제안하는 더 발전적인 기법입니다. '방향을 맞추는 모델'과 '그 시그널을 취해야 할지를 판정하는 모델'을 분리합니다.
# 1단계: 기존의 규칙 기반(rule-based) 또는 심플한 모델로 방향 시그널을 출력
primary_signal = simple_direction_model.predict(X)
# 2단계: 그 시그널을 "취해야 하는가"를 별도의 모델로 판정
...
1단계 모델의 정밀도가 어느 정도 수준이라 하더라도, 2단계가 "확신이 있는 시그널만 걸러내는" 역할을 수행함으로써 전체적인 정밀도와 거래 빈도의 균형을 맞출 수 있습니다. 불균형 데이터 (imbalanced data)에 대한 대처뿐만 아니라, 시그널의 선택과 폐기를 학습시킨다는 발상으로서 유효합니다.
여기서 한 가지, 이전 연재 내용과 연결해 두겠습니다. 트리플 배리어 (Triple Barrier) 법의 라벨은 **전향적 윈도우 (forward-looking window, 미래의 max_holding을 보는 것)**로 만들어집니다. 즉, 인접한 진입 후보들의 라벨은 시간적으로 겹치기 쉽습니다. 이는 연재에서 다루었던 '특징량 누수 (feature leakage)'의 원인 중 하나인 라벨 윈도우의 중첩 그 자체입니다.
트리플 배리어 법을 도입했다면, purge와 embargo는 필수라고 생각하십시오. 라벨 설계를 고안하더라도 분할 설계를 소홀히 하면 다시 똑같은 함정에 빠지게 됩니다.
- 고정 호라이즌 (Fixed Horizon) 라벨은 실제 트레이딩 규칙과 괴리되기 쉽고, 호라이즌을 선택하는 방식도 자의적이기 쉽다.
- 트리플 배리어 법은 익절, 손절, 시간 초과라는 3가지 배리어를 통해 실제 트레이딩 규칙과 정합된 라벨을 만들 수 있다.
- 배리어 폭은 고정값이 아니라, 변동성 (volatility)에 연동시키면 시장 상황의 차이를 흡수할 수 있다.
- 라벨의 불균형에 대해서는 제외, 샘플 가중치, **메타 라벨링 (meta-labeling)**이라는 선택지가 있다.
- 트리플 배리어 법의 라벨은 전향적 윈도우를 가지므로, purge/embargo는 여전히 필수이다.
라벨 설계는 모델의 정밀도 이전에 "무엇을 학습시키고 싶은가"를 정의하는 공정입니다. 이 부분이 모호한 상태에서 하이퍼파라미터 (hyperparameter)를 아무리 조정해도 토대가 어긋난 상태 그대로입니다.
질문이나 "우리 회사는 이런 배리어 설계를 사용하고 있다"라는 이야기가 있다면 댓글로 남겨주세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기