7.8 KiB
Overfitting Analysis — fithia2 overfit-check
전략의 과적합 여부를 학술 논문 기반 5가지 테스트로 종합 검증하는 도구.
빠른 사용법
# 빠른 검사 (~7분, MC 10회 + Permutation 30회)
fithia2 overfit-check --config 415 --quick
# 전체 검사 (~30분, MC 50회 + Permutation 100회)
fithia2 overfit-check --config return_max_long_v7.70
# 특정 테스트만 실행
fithia2 overfit-check --config 415 --skip mc,permutation
# JSON 리포트 저장
fithia2 overfit-check --config 415 --quick --output-json report.json
--config에는 실험 ID(숫자), 이름, 파일 경로 모두 사용 가능.
5가지 테스트
1. DSR (Deflated Sharpe Ratio)
논문: Bailey & Lopez de Prado (2014), "The Deflated Sharpe Ratio"
N번의 전략 시도 중 최고 Sharpe가 운이 아닌 진짜인지 통계적으로 검증한다. 핵심 아이디어: N번 시도하면 random에서도 꽤 높은 Sharpe가 나올 수 있음. DSR은 이 "기대되는 최대 Sharpe"를 계산하고, 실제 관측된 Sharpe가 그보다 유의미하게 높은지 테스트한다.
입력: 같은 parent 계보에서 파생된 모든 sibling 전략의 CW equity curve 출력:
- DSR p-value: 1.0에 가까울수록 유의미 (>0.95 = PASS)
- Sharpe Haircut: Sharpe의 몇 %가 "운"인지
- MinTRL (Minimum Track Record Length): 이 Sharpe가 유의미하려면 최소 몇 일의 데이터가 필요한지
판정 기준:
| DSR p-value | 판정 | 의미 |
|---|---|---|
| > 0.95 | PASS | N번 시도 보정 후에도 통계적으로 유의미 |
| 0.50–0.95 | WARN | 약한 유의미성, 추가 검증 필요 |
| < 0.50 | FAIL | random에서 나올 수 있는 수준 |
예시 해석: "75개 전략을 테스트했고, 최고 Sharpe 3.13의 DSR = 100%. Haircut 14.5% → Sharpe의 85.5%가 실력."
2. PBO (Probability of Backtest Overfitting)
논문: Bailey, Borwein, Lopez de Prado & Zhu (2017), "The Probability of Backtest Overfitting"
IS(In-Sample)에서 최적인 전략이 OOS(Out-of-Sample)에서도 잘하는지를 252가지 데이터 분할로 검증한다.
알고리즘 (CSCV — Combinatorially Symmetric Cross-Validation):
- 전체 기간을 S=10개 시간 블록으로 분할
- C(10,5) = 252가지 조합으로 5블록=IS, 5블록=OOS 구성
- 각 조합에서: IS 최적 전략을 고르고, 그 전략의 OOS 순위를 측정
- PBO = IS 최적이 OOS에서 중앙값 이하인 확률
판정 기준:
| PBO | 판정 | 의미 |
|---|---|---|
| < 10% | PASS | IS 최적화가 OOS에서도 신뢰 가능 |
| 10–30% | WARN | 약간의 과적합 위험 |
| > 30% | FAIL | IS 최적화가 OOS 성과를 해칠 가능성 높음 |
예시 해석: "PBO 5.1%. 252개 조합 중 94.8%에서 IS 최적 전략이 OOS 상위 50%."
3. Parameter Sensitivity (파라미터 민감도)
배경: Harvey, Liu & Zhu (2016), "...and the Cross-Section of Expected Returns"
최적 파라미터 주변에서 성능이 **완만한 고원(plateau)**인지 **급격한 절벽(cliff)**인지 확인한다. 고원이면 robust, 절벽이면 curve-fit.
방법:
- 핵심 파라미터 (per_trade_risk, max_daily_risk 등)를 현재 값의 ±30% 그리드로 변경
- 각 값에서 백테스트 실행
- Sharpe의 변동계수(CV)로 plateau score 계산:
1 - (std/mean)
판정 기준:
| Plateau score | 판정 | 의미 |
|---|---|---|
| > 0.70 | PASS | 넓은 고원 — 파라미터에 둔감 |
| 0.40–0.70 | WARN | 약간의 민감도 |
| < 0.40 | FAIL | 절벽 — 좁은 파라미터에서만 작동 |
4. Monte Carlo Noise Injection (노이즈 주입)
배경: Lopez de Prado (2018), "Advances in Financial Machine Learning"
가격 데이터에 랜덤 노이즈를 넣고 백테스트를 반복해서, 성능이 서서히 줄면 robust, 급락하면 특정 가격 패턴에 curve-fit된 것.
방법:
- 모든 OHLC 가격에
price × (1 + N(0, σ))노이즈 추가 (기본 σ=0.5%) - N회 반복 (기본 50회)하여 Sharpe 분포 생성
- 기준선 대비 중앙값 저하율(degradation) 계산
판정 기준:
| Degradation | 판정 | 의미 |
|---|---|---|
| < 15% | PASS | 노이즈에 대해 완만하게 저하 — 견고한 신호 |
| 15–35% | WARN | 약간 민감 |
| > 35% | FAIL | 특정 가격 수준에 의존 — curve-fit |
예시 해석: "0.5% 노이즈 50회 주입. Sharpe 2.61 → 중앙값 2.18 (16.3% 저하). 5th percentile 1.97."
5. Walk-Forward Permutation Test (순열 검정)
배경: White (2000), "A Reality Check for Data Snooping"
가격 수익률의 시간 순서를 셔플하여 alpha 신호를 파괴한 후 WFV를 실행. 진짜 alpha가 있다면 셔플된 데이터에서는 성능이 나올 수 없다.
방법:
- 원본 데이터로 WFV 실행 → observed Sharpe
- candidate들의 날짜를 랜덤 재배정(alpha 파괴) → N회 반복
- 각 셔플에서 WFV Sharpe 측정 → null distribution 생성
- p-value = null에서 observed 이상인 비율
판정 기준:
| p-value | 판정 | 의미 |
|---|---|---|
| < 0.01 | PASS | 셔플 중 1% 미만만 이 성과 달성 — 강한 alpha |
| 0.01–0.05 | WARN | 약한 유의미성 |
| > 0.05 | FAIL | random에서도 달성 가능한 성과 |
예시 해석: "30회 셔플 중 0회가 관측 Sharpe(3.66) 이상. p=0.000. random이 아닌 진짜 alpha."
종합 점수 (Overall Score)
5개 테스트를 가중 평균하여 0-100 점수와 PASS/WARN/FAIL 판정을 부여한다.
| 테스트 | 가중치 | 이유 |
|---|---|---|
| DSR | 25% | Multiple testing 보정의 핵심 |
| PBO | 25% | Cross-validation 기반 과적합 확률 |
| Sensitivity | 15% | 파라미터 robustness |
| Monte Carlo | 20% | 데이터 noise robustness |
| Permutation | 15% | alpha 존재 여부의 최종 검증 |
| 점수 | 판정 | 의미 |
|---|---|---|
| ≥ 70 | PASS | 전략이 과적합 테스트를 통과 |
| 40–69 | WARN | 일부 위험 신호 — 추가 검토 필요 |
| < 40 | FAIL | 과적합 가능성 높음 — 실전 사용 비추천 |
CLI 옵션
fithia2 overfit-check [옵션]
필수:
--config, -c 실험 ID, 이름, 또는 파일 경로
선택:
--initial-equity 초기 자본 (기본: 10,000)
--quick 빠른 모드 (MC 10회, Perm 30회)
--skip 건너뛸 테스트 (쉼표 구분): dsr,pbo,sensitivity,mc,permutation
--mc-iterations MC 반복 횟수 (기본: 50)
--mc-noise-pct 노이즈 수준 % (기본: 0.5)
--permutations 순열 테스트 횟수 (기본: 100)
--output-json 리포트를 JSON 파일로 저장
실행 시간 예상
| 모드 | MC | Perm | 총 시간 |
|---|---|---|---|
--quick |
10회 | 30회 | ~7분 |
| 기본 | 50회 | 100회 | ~25분 |
정밀 (--mc-iterations 100 --permutations 500) |
100회 | 500회 | ~2시간 |
DSR과 PBO는 기존 실행 결과(equity curve)를 재활용하므로 즉시 완료.
구현 파일
| 파일 | 역할 |
|---|---|
libs/backtest/overfit.py |
핵심 통계 엔진 — DSR, PBO/CSCV, sensitivity, MC, permutation 계산 |
apps/overfit/cli.py |
CLI 진입점, Rich 리포트 포매팅, 백테스트 실행 통합 |
apps/tracker/cli.py |
overfit-check 서브커맨드 라우팅 (line ~877) |
참고 논문
| 테스트 | 논문 |
|---|---|
| DSR | Bailey & Lopez de Prado (2014), "The Deflated Sharpe Ratio" |
| PBO/CSCV | Bailey, Borwein, Lopez de Prado & Zhu (2017), "The Probability of Backtest Overfitting" |
| Haircut SR | Harvey, Liu & Zhu (2016), "...and the Cross-Section of Expected Returns" |
| Reality Check | White (2000), "A Reality Check for Data Snooping" |
| CPCV | Lopez de Prado (2018), "Advances in Financial Machine Learning" |