Your Backtest Is Lying: How Cohort Data Exposes the Gaps
By @CoinMarketMan - 14-Jul-2026
백테스트는 거짓말을 한다: 코호트 데이터가 드러내는 공백
백테스트를 돌렸다. 오픈 인터레스트가 급등하고, 펀딩이 마이너스로 전환됐으며, 신호가 발동됐고, 시뮬레이션 손익은 플러스로 돌아왔다. 샤프 비율은 깔끔하다. 승률은 200번의 거래 전반에 걸쳐 유지된다. 그래서 라이브로 배포했더니, 2주 안에 전략이 손실을 내기 시작한다.
문제는 신호 자체가 아닌 경우가 대부분이다. 신호가 말해줄 수 없는 것이 문제다. 펀딩 전환은 그 전환을 일으키는 지갑이 역사적으로 수익성 있는 트레이더인지, 아니면 연쇄 청산 피해자인지와 무관하게 그냥 펀딩 전환일 뿐이다. OI 급등은 Smart Money 코호트 지갑이 포지션을 쌓고 있든, Giga-Rekt 지갑이 패배 논리에 두 배로 베팅하고 있든 동일하게 보인다. 백테스트는 두 시나리오를 동일하게 취급했는데, 그것들을 구분할 방법이 없었기 때문이다.
바로 그 구분이 코호트 데이터가 채우는 공백이다. HyperTracker는 Hyperliquid의 모든 지갑을 16개의 행동 코호트, 즉 계정 규모에 따른 8개(Shrimp부터 Leviathan까지)와 전체 손익에 따른 8개(Money Printer부터 Giga-Rekt까지)로 분류한다. 이 분류를 백테스트에 레이어로 추가하면, "신호가 발동됐는가?"라고 묻는 대신 "이 거래의 각 측면에 누가 있는가?"를 묻게 된다.
표준 백테스트의 사각지대
Hyperliquid에서 이루어지는 대부분의 백테스트는 가격, 거래량, 오픈 인터레스트, 펀딩 비율을 활용한다. 이것들은 거래소의 공개 API에서 구할 수 있는 입력값이며, 독립적으로 테스트했을 때 잘 작동하는 방향성 신호를 구축하기에 충분하다. 문제는 이것들이 놓치는 것을 볼 때 드러난다.
간단한 롱 신호를 생각해보자: 펀딩이 보합 또는 약간 마이너스 상태에서 OI가 급격히 상승하는 경우다. 표준적인 해석은 새로운 자금이 과도한 캐리 비용 없이 롱 포지션에 진입하고 있다는 것으로, 레버리지 투기보다는 진정한 확신을 시사한다. 백테스트에서 이 패턴은 수백 번의 거래에 걸쳐 소폭 긍정적인 엣지를 만들어낸다.
하지만 집계된 OI는 누구의 확신인지 알려주지 않는다. OI 증가가 주로 Money Printer 코호트(전체 이익 $1M+ 지갑, 세그먼트 ID 8)와 Smart Money 코호트(이익 $100K~$1M, 세그먼트 ID 9)에서 온다면, 정보에 근거한 포지셔닝을 보고 있는 것일 가능성이 높다. 같은 OI 급등이 주로 Giga-Rekt 지갑(평생 -$1M 이하, 세그먼트 ID 15)과 Full Rekt 지갑(-$1M~-$100K, 세그먼트 ID 14)에 의해 주도된다면, 그 "확신"은 항복 매매나 복수 매매일 가능성이 더 높다.
두 시나리오는 동일한 OI 차트를 만들어낸다. 둘 다 동일한 신호를 발동시킨다. 하지만 기대 결과는 의미 있게 다른데, 움직임 뒤에 있는 자본의 질이 중요하기 때문이다.
과거 데이터가 커버하는 범위(그리고 한계)
코호트 컨텍스트를 백테스트에 추가하기 전에, 실제로 어떤 데이터를 사용할 수 있고 얼마나 오래전까지 거슬러 올라갈 수 있는지 이해해야 한다. HyperTracker의 히스토리 엔드포인트는 데이터 유형에 따라 조회 기간이 다르다.
가장 깊은 이력은 포지션에 있다. 개별 포지션 스냅샷은 2025년 4월까지 약 10개월 전으로 거슬러 올라가며, 어느 시점에서도 시장이 어떻게 보였는지 재구성할 원재료를 제공한다. 체결 내역(개별 거래 기록)은 2025년 7월부터 약 6.5개월을 커버하며, 가격 계열을 구축하고 거래 수준의 실행을 분석하는 데 유용하다.
코호트별 데이터는 조회 기간이 더 짧다. 코인별 코호트 메트릭스, 즉 각 세그먼트가 특정 자산에 어떻게 포지셔닝되어 있는지 알려주는 엔드포인트는 API 호출당 약 4주의 조회 기간을 제공한다. 이것이 코호트 기반 백테스팅의 핵심 제약이다. 당시 데이터를 수집하지 않았다면, 6개월 전 BTC에서 Money Printer 코호트가 어떤 행동을 했는지 소급하여 조회할 수 없다.
코호트 바이어스, 즉 특정 코호트의 모든 자산에 걸친 방향성 경향을 측정하는 것은 더 짧다: 롤링 12시간 창. 오더 스냅샷(스탑, 익절, 한계 클러스터)은 약 3주 전으로 거슬러 올라간다. 히트맵과 리더보드는 현재 데이터만 제공하며, 이력 아카이브는 없다.
빌더 팁: 실질적인 함의는 단순하다. 의미 있는 깊이의 코호트 인식 백테스트를 실행하고 싶다면, 지금 당장 데이터 수집을 시작하라. 코호트 메트릭스 엔드포인트를 5분마다 호출하여 응답을 데이터베이스에 기록하는 크론 작업은 한 달이면 한 달치 데이터를, 세 달이면 세 달치 데이터를 제공한다. API의 4주 조회 창은 롤링 창이므로, 직접 저장하지 않으면 이전 데이터는 사라진다.
기존 백테스트에 코호트 필터 레이어 추가하기
백테스트 엔진을 처음부터 다시 구축할 필요는 없다. 가장 깔끔한 접근법은 신호 이후 게이트로서 코호트 필터를 추가하는 것이다. 기존 신호가 후보 거래를 생성하고, 코호트 필터가 어떤 후보를 실행할지, 어떤 것을 건너뛸지 결정한다.
필터는 세 단계로 작동한다:
1단계: 원시 신호 발동. 기존 로직이, 그것이 무엇이든, 거래 기회를 파악한다. OI 급등, 펀딩 다이버전스, 가격 돌파, 이동평균 교차. 신호는 변하지 않는다.
2단계: 코호트 조회. 신호가 발동하는 순간, 관련 자산의 코호트 메트릭스를 조회한다. 두 가지를 확인한다: 어떤 코호트가 신호 방향으로 포지셔닝되어 있는지, 그리고 어떤 코호트가 반대 방향으로 포지셔닝되어 있는지.
3단계: 확신 게이트. 역사적으로 수익성 있는 코호트(Money Printer, Smart Money, Consistent Grinder)가 신호 방향과 일치한다면 거래를 실행한다. 역사적으로 수익성 없는 코호트(Giga-Rekt, Full Rekt, Semi-Rekt)가 주요 동인이고 수익성 있는 코호트가 반대 방향으로 포지셔닝되어 있다면 건너뛴다. 상황이 혼재되어 있다면 크기를 줄이거나 완전히 패스한다.
조회 및 게이트 로직이 실제로 어떻게 보이는지:
import requests
BASE_URL = "https://ht-api.coinmarketman.com/api/external"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}
# 손익 기반 코호트 세그먼트 ID
PROFITABLE = [8, 9, 10] # Money Printer, Smart Money, Consistent Grinder
UNPROFITABLE = [13, 14, 15] # Semi-Rekt, Full Rekt, Giga-Rekt
def fetch_cohort_metrics(coin):
resp = requests.get(
f"{BASE_URL}/cohort/metrics",
headers=HEADERS,
params={"coin": coin}
)
resp.raise_for_status()
return resp.json()
def cohort_conviction(metrics, signal_direction):
"""
신호와 수익성 있는 코호트의 정렬 여부에 따라
'pass', 'skip', 'reduce' 중 하나를 반환한다.
signal_direction: 'long' 또는 'short'
"""
profitable_net = 0
unprofitable_net = 0
for cohort in metrics:
seg = cohort.get("segmentId")
long_n = cohort.get("longNotional", 0)
short_n = cohort.get("shortNotional", 0)
net = long_n - short_n # 양수 = 순 롱
if seg in PROFITABLE:
profitable_net += net
elif seg in UNPROFITABLE:
unprofitable_net += net
# 정렬 여부 판단
if signal_direction == "long":
aligned = profitable_net > 0 and unprofitable_net < profitable_net
opposed = profitable_net < 0
else:
aligned = profitable_net < 0 and unprofitable_net > profitable_net
opposed = profitable_net > 0
if aligned:
return "pass"
elif opposed:
return "skip"
else:
return "reduce"
라이브 백테스트 루프에서는 신호가 발동될 때마다 cohort_conviction()을 호출하고, 그 결과를 사용하여 실행을 게이팅한다. "pass"를 받은 거래는 전체 크기로 실행된다. "reduce"를 받은 거래는 일부 크기로 실행된다(비율은 직접 선택). "skip"을 받은 거래는 절대 실행되지 않는다.
수집 파이프라인 구축
코호트 메트릭스의 조회 기간이 4주이므로, 진지한 백테스팅 작업은 지속적인 데이터 수집을 필요로 한다. 파이프라인은 간단하다: 예약된 스크립트가 API를 호출하고, 응답을 파싱하여 영구 저장소에 기록한다.
import requests
import json
import sqlite3
from datetime import datetime
BASE_URL = "https://ht-api.coinmarketman.com/api/external"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}
COINS = ["BTC", "ETH", "SOL", "HYPE"]
def collect_cohort_snapshot(db_path="cohort_history.db"):
conn = sqlite3.connect(db_path)
conn.execute("""
CREATE TABLE IF NOT EXISTS cohort_snapshots (
timestamp TEXT, coin TEXT, segment_id INTEGER,
long_notional REAL, short_notional REAL,
total_notional REAL, raw_json TEXT
)
""")
ts = datetime.utcnow().isoformat() + "Z"
for coin in COINS:
resp = requests.get(
f"{BASE_URL}/cohort/metrics",
headers=HEADERS,
params={"coin": coin}
)
if resp.status_code != 200:
continue
for cohort in resp.json():
conn.execute(
"INSERT INTO cohort_snapshots VALUES (?,?,?,?,?,?,?)",
(ts, coin, cohort.get("segmentId"),
cohort.get("longNotional", 0),
cohort.get("shortNotional", 0),
cohort.get("totalNotional", 0),
json.dumps(cohort))
)
conn.commit()
conn.close()
크론이나 systemd 타이머로 5분마다 실행하라. 호출당 4개 코인 기준으로, 사이클당 4번의 API 요청을 하게 되는데, 이는 하루 1,152번의 호출이다. 무료 티어의 하루 100번 호출로는 지속적인 수집을 커버하기 어렵지만, $179/월 Pulse 티어는 월 50,000번의 호출을 제공하므로, 여유를 두고 여러 자산에 걸쳐 24/7 수집이 가능하다.
몇 주간의 수집 후에는, 모든 움직임의 각 측면에 누가 있었는지 실제로 반영하는 백테스트를 실행하기에 충분한 코호트 이력 데이터를 갖게 될 것이다.
백테스트가 답해야 할 세 가지 질문
코호트 데이터를 백테스트에 레이어로 추가하면, 가격 전용 백테스트로는 불가능한 질문들을 던질 수 있다:
1. 스마트 머니가 일치할 때 승률은 어떻게 변하는가?
기본 전략을 두 번 실행하라. 한 번은 코호트 필터 없이, 한 번은 필터와 함께. 승률을 비교하라. 필터 버전이 의미 있게 높은 승률을 보이지만 총 거래 횟수가 적다면, 코호트 필터가 제 역할을 하고 있는 것이다. 평균 성과를 끌어내리는 낮은 확신의 거래들을 제거하고 있다.
트레이드오프는 항상 동일하다. 필터는 거래 횟수를 줄인다. 거래 횟수가 적으면 복리 속도가 느려지지만, 낮은 품질의 거래로 인한 드로우다운도 줄어든다. 총 손익이 보합 상태를 유지하더라도 필터링된 샤프 비율이 개선된다면, 전략은 더 자본 효율적이고 크기를 키우기 쉽다.
2. 어떤 코호트 정렬이 가장 중요한가?
모든 코호트가 동등한 예측 가중치를 갖지는 않는다. 각 코호트를 독립적으로 필터로 테스트하라. Money Printer 코호트 하나만의 정렬이 결과를 개선하는가? Leviathan 코호트(퍼프 에쿼티 $5M+ 지갑, 세그먼트 ID 7)는 어떤가? 규모 기반 코호트와 손익 기반 코호트는 서로 다른 것을 측정하며, 어느 것이 가장 중요한지는 거래 중인 자산과 시간대에 따라 달라진다.
BTC와 ETH 같은 대형 자산의 경우, 손익 기반 코호트가 더 유익한 경향이 있는데, 시장이 충분히 깊어서 규모 자체만으로는 방향성을 예측하기 어렵기 때문이다. 중형 및 롱테일 자산의 경우, 규모 기반 코호트가 더 중요할 수 있는데, 단일 Whale이나 Leviathan 지갑의 포지션 진입이 전체 오픈 인터레스트에서 더 큰 비중을 차지하기 때문이다.
3. 코호트 다이버전스가 드로우다운을 예측하는가?
백테스팅에서 코호트 데이터의 가장 가치 있는 활용 중 하나는 드로우다운 분석이다. 백테스트의 최악의 손실 구간을 살펴보고, 진입 시점의 코호트 구성을 확인하라. 최악의 드로우다운이 신호가 수익성 없는 코호트와 일치하고 수익성 있는 코호트에 의해 반대되는 순간과 일관되게 겹친다면, 표준 백테스트로는 절대 드러나지 않았을 전략의 구조적 취약점을 발견한 것이다.
이것이 코호트 인식 백테스팅의 진정한 수익이다. 단순히 평균 성과를 개선하는 것이 아니라, 전략이 가장 취약한 특정 조건을 파악하는 것이다. 그것은 평균 수익률의 몇 베이시스 포인트 추가보다 훨씬 가치 있다.
코호트 데이터로 백테스팅할 때 흔한 함정
코호트 데이터는 강력한 렌즈를 추가하지만, 그 자체의 실패 모드도 있다.
특정 코호트에 과적합. Money Printer 코호트만 따르도록 전략을 최적화했는데 백테스트 결과가 훌륭하다면, 스스로에게 물어보라: 실제 신호를 거래하고 있는가, 아니면 테스트 기간에 우연히 맞았던 소수 지갑에 맞추고 있는가? Money Printer 코호트는 시장의 좁은 단면을 대표한다. 한 세그먼트의 포지셔닝에만 전적으로 의존하는 전략은 취약하다.
코호트 레짐 변화 무시. 지갑은 시간이 지남에 따라 코호트 간을 이동한다. 1월에 Smart Money였던 지갑은 연속 손실 후 6월에 Semi-Rekt가 될 수 있다. HyperTracker는 전체 손익에 따라 지갑을 재분류하므로, 코호트 레이블은 동적이다. 정적 코호트 멤버십을 가정하는 백테스트는 신호 품질을 과대평가하는데, 따르고 있는 "스마트 머니" 포지셔닝 중 일부가 당시에는 스마트했지만 더 이상 그렇지 않은 지갑에 의해 생성된 것이기 때문이다.
지연 시간 가정. 데이터는 5분마다 갱신되며, 전체 상태 갱신에는 15~20분이 걸린다. 백테스트에서는 모든 타임스탬프에서 완벽한 데이터를 가진다. 라이브 트레이딩에서는 항상 몇 분 전 데이터를 보고 있다. 현재 봉 코호트 데이터 대신 이전 스냅샷의 코호트 데이터를 사용하여 백테스트에 이 지연을 반영하라. 신호가 현재 봉 코호트 데이터로만 작동한다면, 실거래에서는 작동하지 않는다.
상관관계와 인과관계 혼동. 스마트 머니 포지셔닝이 가격을 특정 방향으로 움직이게 하는 것은 아니다. 그것은 동행 지표다. 수익성 있는 지갑은 수익성 없는 지갑보다 더 자주 올바른 방향으로 포지셔닝하는 경향이 있을 뿐이다. 그 관계는 확률적이지 결정론적이지 않다. 코호트 정렬을 단일 거래에 대한 보장이 아니라, 많은 거래에 걸쳐 기대 가치를 개선하는 필터로 취급하라.
백테스트를 위한 코호트 데이터 수집 시작하기
무료 티어는 하루 100번의 API 호출을 제공한다. 규모를 키우기 전에 수집 파이프라인을 시험하고 신호 품질을 검증하기에 충분하다.
모든 백테스트는 현실의 단순화된 모델이다. 어떤 단순화가 돈을 잃게 하는지가 핵심이다. 모든 자본을 동등하게 취급하고, 흐름 뒤에 누가 있는지 무시하며, 출처에 관계없이 OI는 OI라고 가정하는 것. 이런 단순화들은 전략을 라이브로 배포하고 시뮬레이션 곡선 대비 언더퍼폼하는 것을 지켜보기 전까지는 무해해 보인다. 코호트 데이터가 백테스트를 완벽하게 만들어주지는 않는다. 거짓말을 더 작게 만들어줄 뿐이며, 그것으로 결과를 바꾸기에 충분하다.