대부분의 크립토 백테스트는 무가치합니다. 실거래에서 살아남을 수 없는 버그가 가득해서 천문학적 수익률을 보여줍니다. 올바르게 하는 방법을 알려드립니다.
백테스트란?
백테스트는 트레이딩 전략을 과거 시장 데이터에 대해 테스트하여 어떤 성과를 냈을지 확인하는 것입니다. 규칙(매수 시점, 매도 시점, 포지션 크기, 손절)을 정의하고 과거 가격 데이터에서 실행을 시뮬레이션합니다.
왜 중요한가: 백테스트 없이는 도박입니다. 제대로 된 백테스트가 있으면, 전략에 우위가 있는지에 대한 통계적 증거를 갖게 됩니다.
왜 대부분의 백테스트가 거짓인가: 백테스트와 실거래 사이의 격차는 엄청납니다. 우리의 Momentum LONG 전략은 백테스트에서 +400%였지만 캔들 인덱스 버그 수정 후 음의 기대값을 보였습니다. 차이점? 엄격한 검증에서만 드러나는 버그입니다.
백테스트의 유형
모든 백테스트가 동일하지 않습니다. 규칙에 들어가기 전에 세 가지 주요 접근법을 이해하세요.
워크포워드 분석 (Walk-Forward Analysis): 데이터를 순차적 윈도우로 분할합니다. 윈도우 1에서 최적화하고, 윈도우 2에서 테스트합니다. 그런 다음 윈도우 1+2에서 최적화하고, 윈도우 3에서 테스트합니다. 이것은 과거 데이터만 가지고 작업하는 실제 상황을 모방합니다. 주기적 재최적화를 통해 전략이 시간에 따라 어떻게 진화할지 시뮬레이션하는 가장 가까운 방법입니다.
몬테카를로 시뮬레이션 (Monte Carlo Simulation): 거래 순서를 랜덤화하거나 파라미터를 약간 변경하여 수천 번 반복 실행합니다. 전략이 정확한 과거 순서에서만 작동한다면 취약한 것입니다. 몬테카를로는 단일 과거 경로가 아닌 결과의 확률 분포를 알려줍니다. 95번째 백분위 최대 드로다운이 40%인 전략과 15%인 전략은 평균 수익이 같더라도 완전히 다릅니다.
아웃오브샘플 테스트 (Out-of-Sample Testing): 가장 기본적이고 가장 중요합니다. 우리가 실제로 쓰는 분할은 2024 학습 / 2025 검증 / 2026 표본외입니다(SL·TP 최적화 가이드가 그 절차의 소유자). 모델이 본 적 없는 기간에서 테스트합니다. 성능이 크게 떨어지면 과적합입니다. 이것은 타협 불가능합니다 — 아웃오브샘플 검증이 없는 백테스트 결과는 본질적으로 무가치합니다.
각 접근법은 다른 실패 모드를 포착합니다. 워크포워드는 레짐 의존 과적합을, 몬테카를로는 순서 의존 취약성을, 아웃오브샘플은 일반 과적합을 잡습니다. 결과에 자신감을 가지려면 세 가지 모두 사용하세요.
정직한 백테스트의 5가지 핵심 규칙
규칙 1: 완성된 캔들만 사용
크립토 백테스트에서 가장 흔하고 가장 위험한 실수입니다.
봇이 10:01 UTC에 실행될 때, 9:00-10:00 캔들은 완성되었습니다(확정된 데이터). 10:00-11:00 캔들은 아직 형성 중입니다(미확정 데이터).
잘못된 방식: 현재 캔들의 볼륨, 종가, 지표를 진입 조건으로 사용. 백테스트에서 “현재” 캔들은 이미 완성되어 있지만, 실거래에서는 1분치 데이터만 있습니다.
올바른 방식: 모든 시그널 조건은 이전(완성된) 캔들을 사용. 체결은 다음 캔들의 시가로. 시그널이 난 봉의 종가는 결정 시점에 아직 존재하지 않으므로 진입가가 될 수 없습니다 — 우리 엔진도 시그널 봉의 다음 봉 오픈에서 체결합니다.
# 올바름: 이전 캔들로 시그널, 현재 캔들로 진입가
signal = prev_candle['bb_squeeze'] == True and prev_candle['volume_ratio'] > 2.0
entry_price = curr_candle['close']
# 잘못됨: 현재 캔들 데이터 사용 (선행 편향)
signal = curr_candle['bb_squeeze'] == True # 이 데이터는 아직 존재하지 않습니다!
규칙 2: 백테스트 로직을 실거래 로직과 정확히 일치시킬 것
백테스트 코드와 실거래 코드는 동일한 데이터가 주어지면 동일한 시그널을 생성해야 합니다. 하나의 인덱스 차이만으로도 결과가 완전히 바뀔 수 있습니다.
우리의 교훈: 백테스트에서 prev vs prev2 캔들 비교가 실거래 코드와 달랐던 적이 있습니다. 백테스트는 -20.6% 손실을 보여줬습니다. 실거래 로직과 정확히 일치하도록 수정하니 +$794 수익이었습니다. 인덱스 하나 차이. 완전히 반대 결과.
검증 방법:
- 실거래 코드에서 시그널 함수를 추출
- 백테스트에서 그 함수를 그대로 사용
- 동일한 데이터에서 양쪽을 실행하고 시그널 비교
규칙 3: 모든 비용 포함
거래당 평균 +3% 수익을 보여주는 전략도 비용을 반영하면 적자가 됩니다:
- 거래 수수료: OKX USDT 무기한 선물 메이커 0.02% / 테이커 0.05% — 마켓 주문 왕복은 0.1%(양방향 테이커)
- 슬리피지: 시장가 주문은 표시 가격에 체결되지 않음. 우리 엔진은 유동성 3티어로 체결당 0.05%(상위 50) · 0.10%(상위 200) · 0.20%(그 외)를 뗍니다 — 진입과 청산에 각각 붙으므로 왕복은 그 두 배
- 펀딩비: 무기한 선물은 8시간마다 정산됩니다. 출처는 우리가 수집한 BTC 정산 이력(Binance USDT-M perpetual BTCUSDT, 정산 3,002건, 2023-12-31 → 2026-09-27)입니다. 그 기간 평균 0.0064%/8h · 단일 최고 0.0881% 였고 0.1% 는 한 번도 기록되지 않았습니다 (수수료 가이드가 그 표의 소유자)
- 스프레드: 저유동성 알트코인은 0.1-0.5%의 매수-매도 스프레드
최소 비용 가정: 오늘의 OKX 요율, 상위 50 코인 기준 왕복 0.20% — 테이커 0.05% × 2 = 0.1%, 슬리피지 0.05% × 2 = 0.10%. (이 자리에 0.15% 라고 적혀 있었는데, 수수료는 왕복으로 세고 슬리피지는 편도만 센 값입니다.)
규칙 4: 충분한 데이터로 테스트
6개월 데이터에서 작동하는 전략은 아무것도 증명하지 못합니다. 시장에는 레짐이 있습니다 — 상승장, 하락장, 횡보장, 고변동성, 저변동성. 백테스트는 여러 레짐을 포함해야 합니다.
당시 기준(OKX 이전 아카이브 런, 데이터 2023-12 → 2026-02): 535개 코인, 2년+ 시간봉 데이터(바이낸스 USDT 무기한 선물). 이를 통해 다양한 시장 조건에서 2,898건의 거래를 얻었습니다. 오늘날 같은 기준은 코인 단위로 표현됩니다: 엔진은 각 코인을 우리가 수집한 가격 이력으로 백테스트합니다 — 우리 수집이 시작되기 전에 상장된 코인은 상장 이후가 아니라 수집 시작부터입니다.
아웃오브샘플 검증: 데이터를 훈련(파라미터 최적화)과 테스트(결과 검증)로 분리합니다. 양쪽에서 작동하면 실제일 가능성이 높습니다. 훈련 데이터에서만 작동하면 과적합입니다.
규칙 5: 현실적인 포지션 사이징 사용
수익률을 백분율로 계산해서 합산하지 마세요. 실제 자금 배분을 시뮬레이션하세요.
# 잘못됨: 단순 백분율 합산 (환상)
total_return = sum(trade_returns) # +2,090% 표시
# 올바름: 실제 계좌 잔액 시뮬레이션
balance = 10000 # 시작 자본
for trade in trades:
position_size = min(200, balance * 0.02) # $200 또는 잔액의 2%
pnl = position_size * trade_return * leverage
balance += pnl
# +103% 표시 (현실)
차이점? 단순 합산은 손실 거래가 향후 거래의 자본을 줄인다는 것을 무시합니다. 현실적 시뮬레이션은 실제 손익이 어떨지 보여줍니다.
우리가 실제로 거는 문턱
«건강한 범위»를 지어내는 대신, 이 사이트가 실제로 판정에 쓰는 값만 적습니다. 줄마다 그 값을 소유한 코드가 있습니다:
| 지표 | 문턱 | 무슨 뜻인가 | 소유자 |
|---|---|---|---|
| 수익 팩터 | 1.5 이상 / 1.0 이상 / 1.0 미만 | 1.0 은 손익분기(총이익 = 총손실)라 정의이지 측정으로 고른 값이 아닙니다 | src/utils/format.ts profitFactorTier |
| 승률 | 55% 이상 / 50% 이상 / 50% 미만 | 손익분기 승률을 아는 화면에서는 그 값을 대신 씁니다 — 승률만으로는 좋고 나쁨이 안 정해집니다 | 같은 파일 winRateTier |
| 표본 수 | 30건 미만 | 결과가 잡음 대역 안이라 «성과 추정»이 아닙니다 | backend/api/schemas.py build_reliability_checks |
| 표본 수 | 100건 미만 | 랭킹에 «샘플 부족» 경고가 붙습니다 | LOW_SAMPLE_MIN_TRADES |
| 레버리지 × 손절 | 90 이상 | 대부분의 거래가 청산으로 끝납니다 | 같은 파일 leverage 축 |
| 사용 코인 수 | 1개 | 그 코인의 레짐이지 분산된 엣지가 아닙니다 | 같은 파일 diversification 축 |
우리가 무엇을 지웠고 왜 지웠는지. 이 자리에는 원래 «건강한 범위 / 위험 신호» 표가 있었습니다 — 승률 50-70%, 수익 팩터 1.5-3.0, 최대 드로다운 10-30%, 샤프 비율 1.0-3.0, 표본 500건 이상, 그리고 위험 신호 >80% · >5.0 · >50%. 그 수들의 출처가 우리 안에 없습니다: 코드에도 없고 측정 기록에도 없으며, 우리는 어디서도 그 범위로 판정하지 않습니다. 최대 드로다운과 샤프 비율은 문턱 자체가 없어서 위 표에 줄이 없습니다 — 넣으려면 또 지어내야 합니다. 출처 없는 임계는 표로 그려질수록 잘 인용되고 덜 검증됩니다.
사례 — BB Squeeze SHORT (이후 폐기): 승률 68.6%, 수익 팩터 2.22, 535개 코인에서 2,898건 거래(아카이브 런, 데이터 2023-12 → 2026-02). 이 수치는 2024, 2025, 2026 데이터에서 아웃오브샘플 검증을 통과했지만 — 2026-06-28 신규 표본외 재검증에서 탈락해 폐기했습니다 (전략 저널). 정직한 백테스트조차 상한선이지 약속이 아닙니다.
흔한 백테스트 실수
아래 다섯 함정은 우리 엔진이 각각을 어떻게 다루는지 보여 주는 독립 페이지가 있습니다: 백테스트가 실패하는 이유.
과적합
백테스트 결과를 개선하려고 조건을 계속 추가하는 것. 추가된 조건마다 과거 데이터에 더 잘 맞지만 새로운 데이터에 대한 일반화는 나빠집니다.
테스트: 조건 하나를 제거했을 때 결과가 망가지면 과적합일 가능성이 높습니다. 견고한 전략은 작은 파라미터 변경에도 살아남아야 합니다.
생존자 편향
현재 존재하는 코인에서만 테스트하는 것. 상장폐지된 코인(대부분 99% 폭락 후)이 제외되어 결과가 실제보다 좋아 보입니다.
해결: 상장폐지 코인을 데이터에 포함하거나, 최소한 이 한계를 인정하세요.
시장 레짐 무시
하락장에서 작동하는 전략이 상승장에서 완전히 실패할 수 있습니다. 시장 조건에 적응하는 것이 도움이 되는지 4가지 BTC 레짐 필터를 테스트했습니다. 4개 모두 실패 — 놓친 거래의 비용이 손실 방지 효과를 초과했습니다.
교훈: 때로는 최고의 필터는 필터를 쓰지 않는 것입니다. 데이터가 결정하게 하세요.
흔한 백테스트 실수 (사례 연구)
위의 실수들은 추상적입니다. 실제 돈을 어떻게 파괴하는지 세 가지 구체적 사례를 봅시다.
사례 1: 선행 편향 — 값비싼 교훈
저희 팀이 Momentum LONG 전략을 개발했는데 18개월간 +400% 수익률을 백테스트에서 보여줬습니다. 에쿼티 커브는 매끈했고, 샤프 비율은 3.0 이상이었고, 드로다운도 관리 가능했습니다. 실거래 자금을 배분했습니다.
문제: 시그널 함수가 현재 캔들의 볼륨 급등을 읽어 진입을 트리거했습니다. 백테스트에서 그 캔들은 이미 완성 — 볼륨 급등이 확인된 상태입니다. 실거래에서는 봇이 실행될 때 캔들이 겨우 1분 열려 있습니다. “볼륨 급등”은 아직 존재하지 않습니다. 캔들 인덱스 버그를 수정하고 재테스트하니 전략은 음의 기대값을 보였습니다. 버그를 발견하기 전에 이미 상당한 자금을 실거래에서 잃었습니다. 규칙 1(완성된 캔들만)이 타협 불가능한 이유입니다. 인덱스 오프셋 하나가 +400% 우승자를 돈 잃는 전략으로 바꿨습니다.
사례 2: 생존자 편향 — 상위 50개 코인만 테스트
흔한 지름길은 오늘의 시가총액 상위 50개 코인으로 백테스트하는 것입니다. 논리는 그럴듯해 보입니다 — 가장 유동성 높고 가장 많이 거래되는 자산이니까요. 하지만 문제가 있습니다: 오늘의 상위 50개 코인은 성공했기 때문에 선택된 것입니다. 95% 폭락하고 상장폐지된 코인 — LUNA, FTT, 2021년의 수십 개 DeFi 토큰 — 은 제외됩니다.
모멘텀 시그널에 롱 진입하는 전략은 생존자만 테스트하면 부풀려진 수익을 보여줍니다. 그래서 우리 BB Squeeze SHORT 수치(당시 런 기준 승률 68.6%, 수익 팩터 2.22)는 상장폐지 포함 전체 535개 코인에서 측정됐습니다 — 유니버스가 전사자를 보존하므로 생존자 편향이 결과를 조용히 부풀릴 수 없습니다. 생존자-온리 지표로 포지션을 설정하면 데이터가 실제로 지지하는 것보다 큰 리스크를 지게 됩니다.
사례 3: 과적합 — 25개 파라미터 전략
한 트레이더를 상상해 봅시다(특정 인물이 아닌 합성 예시) — 25개 조절 파라미터의 정교한 평균회귀 전략을 만듭니다: RSI 기간, RSI 과매수 임계값, RSI 과매도 임계값, 볼린저 밴드 기간, BB 표준편차, MACD 패스트/슬로우/시그널 기간, 볼륨 필터 윈도우, 볼륨 배수, ATR 기간, 손절 ATR 배수, 추적 손절 활성화, 추적 손절 거리, 시간대 필터 시작/종료, 요일 필터, 최소 스프레드 필터, 최대 보유 시간, 재진입 쿨다운 등.
이 예시에서 백테스트는 승률 92%·수익 팩터 8.0+를 보여주지만 — 라이브 첫 주에 돈을 잃습니다. 25개 파라미터와 2년치 시간봉이면 옵티마이저가 노이즈를 완벽히 암기할 자유도가 충분합니다. 4개 핵심 파라미터(BB 기간·편차·SL%·TP%)로 줄이면 화려한 승률은 내려가지만 강건성은 올라갑니다. 적은 파라미터 + 많은 데이터가 복잡한 모델을 항상 이깁니다. (이 시나리오는 기록된 실험이 아닌 교육용 모델입니다.)
PRUVIQ가 이런 문제를 처리하는 방법
PRUVIQ의 모든 전략은 정확히 이런 문제들을 포착하도록 설계된 검증 파이프라인을 거칩니다.
몬테카를로 검증: 단일 백테스트 에쿼티 커브를 보고하지 않습니다. 1,000회 몬테카를로 반복으로 거래 순서를 부트스트랩(재셔플)해 에쿼티 경로의 취약성을 봅니다. 정확한 과거 순서에서만 좋아 보이면 그 취약성이 여기서 드러납니다. PRUVIQ 시뮬레이터에서 직접 확인할 수 있습니다.
아웃오브샘플 테스트: 모든 전략은 한 기간에서 학습되고 완전히 별개의 기간에서 검증됩니다(분할은 위와 같은 2024 / 2025 / 2026). BB Squeeze SHORT는 양 구간 모두에서 수익 팩터 우위가 나왔습니다 — IS 1.29 / OOS 1.08. 2026-06-28 신규 표본외 재검증이 횡보 구간의 적대 축 3개에서 이를 기각해 폐기했습니다: 그 우위는 방향성 실력이 아니라 베어-베타였습니다. 2026-08-17 에 «조건부»로 재분류됐고 현재 상태의 소유자는 저널 입니다. 아웃오브샘플 통과는 필요조건이지 충분조건이 아닙니다. 성능이 떨어지는 전략은 — OOS든 라이브든 — 숨기지 않고 폐기(killed)로 표시합니다.
실제 수수료 모델링: 진입·청산 양쪽에 0.05% 단일 요율(OKX USDT 무기한 선물 기본 테이커 요율)을 겁니다 — 시뮬레이터의 코인 유니버스를 OKX USDT-SWAP 상장 목록에서 뽑기 때문입니다. 여기에 유동성 티어별 슬리피지(0.05–0.20%)와 펀딩비 비용 가정을 더합니다. “제로 비용” 환상은 없습니다. 수수료 페이지에 전체 요율표, OKX 원문과 마지막으로 대조한 날짜, 레퍼럴로 저희가 받는 몫이 있습니다. (공시: 그 페이지의 OKX 추천 링크는 제휴(Affiliate) 링크 — 그 링크로 가입하면 저희가 커미션을 받습니다.)
폐기 전략 공개: 우리가 테스트하는 대부분의 전략 설정이 검증에 실패하며(현재 시뮬레이터에 킬 프리셋 11종 공개) 전체 데이터와 함께 공개 문서화되어 있습니다. 실패를 숨기지 않습니다 — 검증 프로세스가 실제로 작동한다는 증거입니다. 성공만 보여주는 플랫폼은 정직하게 테스트하지 않는 플랫폼입니다.
체크리스트: 백테스트를 신뢰하기 전에
백테스트된 전략에 실제 돈을 투입하기 전에 — 자신의 전략이든 타인의 전략이든 — 이 10개 항목을 확인하세요.
- 완성된 캔들만: 모든 시그널 조건이 이전(종료된) 캔들을 사용. 진입 로직에 현재 캔들 데이터 없음.
- 코드 동일성: 백테스트 시그널 함수가 실거래 시그널 함수와 동일. 동일 데이터셋에서 양쪽 실행 후 출력 비교로 확인.
- 현실적 비용: 수수료, 슬리피지, 스프레드, 펀딩비 포함. 유동성 높은 선물 기준 총 왕복 비용 최소 0.20%(진입·청산 양쪽에 수수료와 슬리피지가 붙는지 확인).
- 충분한 데이터: 상승장, 하락장, 횡보장을 포함하는 최소 2년. 표본은 최소 30건(그 아래는 잡음 대역), 랭킹에 경고 없이 서려면 100건 이상 — 위 표의 소유 코드와 같은 값입니다.
- 아웃오브샘플 검증: 최적화에 사용되지 않은 데이터에서 전략 테스트. 인샘플 대비 성능 저하 20% 이내.
- 생존자 편향 대응: 데이터셋에 상장폐지/폭락 코인 포함, 또는 한계를 명시적으로 인정.
- 파라미터 수 통제: 단순 전략 기준 8개 미만의 자유 파라미터. 각 파라미터에 경제적 근거.
- 몬테카를로 생존: 1,000회 이상 랜덤 반복에서 양의 기대값 유지.
- 현실적 포지션 사이징: 단순 백분율 합산이 아닌 실제 자금 배분으로 시뮬레이션.
- 체리피킹 없는 기간: 결과가 특정 시작일/종료일에 의존하지 않음.
하나라도 실패하면 백테스트를 신뢰할 수 없습니다. 돌아가서 문제를 수정하고 재테스트하세요.
FAQ
통계적으로 유의한 백테스트에 몇 건의 거래가 필요한가요?
우리 코드가 실제로 거는 문턱은 30건(그 아래는 잡음 대역이라 결과를 «성과 추정»으로 쓰지 않습니다)과 100건(랭킹에 «샘플 부족» 경고가 붙는 선)입니다 — 위 표의 소유 코드와 같은 값입니다. 종전 이 답에 적혀 있던 «최소 500건»은 우리 문턱이 아니라 출처 없는 눈금이라 지웠습니다. 우리의 BB Squeeze SHORT 전략은 535개 코인에서 2,898건 거래를 사용했고 — 그런데도 라이브에서 실패했습니다. 표본 크기는 노이즈를 막아주지, 레짐 변화를 막아주지 않습니다.
TradingView에서 백테스트할 수 있나요?
TradingView의 Strategy Tester는 빠른 검증의 좋은 출발점이지만 상당한 한계가 있습니다. 현실적인 슬리피지를 모델링하지 않고, 단순화된 수수료 구조를 사용하며, 현재 캔들 데이터(선행 편향)를 실수로 사용하기 쉽습니다. 진지한 검증을 위해서는 로직을 Python으로 내보내고 적절한 비용 모델링으로 실행하세요. TradingView는 아이디어 생성용으로, 최종 검증용으로는 사용하지 마세요.
전략 파라미터를 얼마나 자주 재최적화해야 하나요?
재최적화는 양날의 검입니다. 너무 자주(매주) 하면 최근 노이즈에 커브피팅하게 됩니다. 너무 드물게(전혀 안) 하면 시장 미시구조가 변하면서 전략이 표류할 수 있습니다. 우리의 접근법: 워크포워드 분석을 사용해 분기별로 재검증합니다. 아웃오브샘플 성능이 인샘플의 50% 아래로 떨어지면 조사합니다. 하지만 지난달이 나빴다고 파라미터를 바꾸지는 마세요 — 그것이 작동하는 전략을 과적합된 전략으로 바꾸는 방법입니다.
백테스트와 페이퍼 트레이딩의 차이점은?
백테스트는 과거 데이터에서 전략을 실행합니다 — 빠르고(몇 분에서 몇 시간) 수년간의 시장 조건을 다룹니다. 페이퍼 트레이딩은 시뮬레이션 자금으로 실시간으로 전략을 실행합니다. 페이퍼 트레이딩은 백테스트가 놓치는 버그를 잡습니다: API 지연, 주문 체결 문제, 속도 제한, 거래소 다운타임. 둘 다 필요합니다. 먼저 백테스트로 나쁜 전략을 빠르게 걸러내고, 생존한 전략을 실제 자금 투입 전 최소 2-4주 페이퍼 트레이딩하세요. 코드 작성 없이 백테스트를 실행하려면 PRUVIQ 시뮬레이터를 사용해 보세요.
시작하기
- 데이터 확보: 거래소 API에서 OHLCV(시가, 고가, 저가, 종가, 거래량) 캔들 데이터 다운로드
- 규칙 정의: 명확하고 모호하지 않은 진입/청산 조건 작성
- 시뮬레이션: 과거 데이터를 캔들 단위로 순회하며 포지션과 손익 추적
- 검증: 데이터를 훈련/테스트 기간으로 분리. 선행 편향 확인
- 소액 시작: 검증을 통과하면 실시장에서 최소 포지션으로 테스트
백테스트와 실거래 사이의 격차에서 대부분의 전략이 죽습니다. 정직한 백테스트가 그 격차를 줄입니다.
PRUVIQ에서는 실패한 전략도 내리지 않고 공개해 둡니다. 실패한 전략과 버전 이력에서 전체 투명성 기록을 확인하세요.