Sweet Spot 0.8%는 7일 노이즈에 fit된 값이었다 — V4.2 → V4.3.1 백테 일지
V4.3.1 (Trail Activate 0.8%)는 7일 백테에서 +$0.601, PF 1.20을 찍었습니다. 같은 코드로 30일을 돌렸더니 -$1.65, PF 0.74가 나왔습니다. 오버피팅의 표준적 증상을 정면에서 만난 기록.
받은 영수증부터
V4.3.1 백테스트 결과 — 같은 전략 코드, 같은 수수료, 같은 슬리피지, 다른 윈도우.
| 윈도우 | 거래 수 | WR | Net PnL | PF | Sharpe | Max DD |
|---|---|---|---|---|---|---|
| 7일 | 108 | 64.8% | +$0.601 | 1.20 | 9.3 | 0.44 |
| 30일 | 239 | 46.4% | -$1.65 | 0.74 | -2.8 | 1.93 |
같은 전략입니다. 다른 시장 구간일 뿐.
학계 표준 진단으로는 Sharpe 40% 이상 하락 또는 Max DD 2배 이상 증가 = 오버피팅입니다. 우리 케이스는 Sharpe 130% 하락, Max DD 4.4배 증가. 양쪽 임계치 모두 큰 폭으로 초과했습니다.
V4.2부터 어떻게 여기까지 왔는가
V4.2 — MIN_PROFIT을 1.2% → 1.5%로 올렸는데 결과가 똑같았다
V3.7.1 라이브 R:R이 0.46이었습니다 (평균 익절 +$0.08 / 평균 손절 -$0.18). 손익비를 개선하기 위해 가장 직관적인 변경을 시도했습니다 — 안전망 익절선을 1.2%에서 1.5%로 올리는 것.
7일 백테 결과:
| 버전 | MIN_PROFIT | 거래 수 | WR | PnL | R:R |
|---|---|---|---|---|---|
| V3.7.1 베이스 | 1.2% | 128 | 64.1% | +$0.295 | 0.60 |
| V4.2 | 1.5% | 128 | 64.1% | +$0.295 | 0.60 |
완전히 동일했습니다.
원인을 찾기 위해 청산 사유를 분해해보니:
- TRAIL_TP (트레일링 익절): 72건 (승리의 88%)
- LIMIT_TP (안전망 익절): 10건
- STOP_LOSS: 37건
- TIMEOUT: 19건
승리 거래의 88%가 트레일링 익절로 먼저 청산되고 있었습니다. MIN_PROFIT 안전망에 가격이 닿기 전에 트레일링이 이미 익절시켜버렸기 때문에, 안전망을 올려도 효과가 없었던 것.
교훈: 변경하는 변수가 실제로 효과를 발휘하는 자리에 있는지부터 확인해야 한다. 88% 거래가 다른 경로로 청산되고 있었다는 사실은 백테 결과를 분해하기 전까지 보이지 않았습니다.
V4.3 — Trail Activate를 0.6% → 1.0%로 올렸더니 마이너스가 났다
지배적 청산 경로 (TRAIL_TP)를 직접 손대기로 했습니다. 트레일링 활성화 임계값을 0.6%에서 1.0%로 늦추면 작은 펌프(+0.6~0.9%)는 무시하고 진짜 추세에서만 트레일링이 잡힐 거라는 가설.
| 버전 | Trail Activate | WR | PnL | PF | 평균 익절 |
|---|---|---|---|---|---|
| V4.2 | 0.6% | 64.1% | +$0.295 | 1.08 | +$0.048 |
| V4.3 | 1.0% | 56.3% | -$0.291 | 0.94 | +$0.061 |
평균 익절은 27% 올랐습니다 (가설 일부 적중). 하지만 승률이 7.8%p 폭락하면서 PnL이 마이너스로 전환됐습니다.
원인은 STOP_LOSS 폭증 (37건 → 45건). 0.7~0.99% 사이에서 정점을 찍고 꺾이는 거래들이 트레일링 활성화 못 받고 결국 손절선까지 내려가버린 것. 0.6%에서는 작은 익절($0.05)이라도 받았던 거래들이 1.0%에서는 손실(-$0.18)로 전환.
교훈: 가설이 절반 맞을 수도 있다. 평균 익절을 늘렸다는 건 사실이지만, 그 대가로 손실 전환 빈도가 따라온다. 한 변수의 개선이 다른 지표의 악화를 동반할 수 있다는 걸 숫자로 직접 본 것.
V4.3.1 — 0.8%로 내렸더니 진짜 좋아졌다 (7일에선)
1.0%가 너무 높았으니 0.6%와 1.0% 사이를 잡았습니다.
| 버전 | Trail | WR | PnL | PF | 평균 익절 |
|---|---|---|---|---|---|
| V4.2 | 0.6% | 64.1% | +$0.295 | 1.08 | +$0.048 |
| V4.3 | 1.0% | 56.3% | -$0.291 | 0.94 | +$0.061 |
| V4.3.1 | 0.8% | 62.7% | +$0.456 | 1.12 | +$0.053 |
V4.2 대비 PnL +33%, 승률 거의 보존. "Trail 0.8% = sweet spot" 확정.
여기서 멈추고 라이브로 갔으면 망했을 겁니다.
Grid Search — 0.85%에서 절벽이 있다
0.8%가 진짜 최적인지 확인하기 위해 인접 값을 추가로 백테했습니다.
| Trail | WR | PnL | PF | Max DD |
|---|---|---|---|---|
| 0.70% | 62.7% | +$0.282 | 1.08 | 0.50 |
| 0.75% | 62.7% | +$0.348 | 1.09 | 0.49 |
| 0.80% | 62.7% | +$0.456 | 1.12 | 0.44 |
| ─── 절벽 ─── | ||||
| 0.85% | 58.4% | -$0.227 | 0.95 | 0.96 |
| 0.90% | 57.6% | -$0.355 | 0.92 | 0.96 |
| 1.00% | 56.5% | -$0.229 | 0.95 | 0.84 |
0.70% → 0.80% 매끄럽게 상승, 0.85%부터 PnL 마이너스 + Max DD 2배. 7일 데이터 안에서 0.80~0.85% 구간에서 정점 찍고 꺾인 특정 거래들이 있었던 것.
이 시점에서 0.8%가 sweet spot이라는 결론에 자신감이 붙었습니다. 인접 값도 검증했고, 절벽 패턴도 명확하니까.
HYPER 종목별 분석 — 30개 백테에서 PnL이 한 자리도 변하지 않는 종목
종목별 PnL을 뜯어봤습니다.
7일 기준 (Trail 0.8%):
| 종목 | 거래 수 | WR | Cum PnL | PF |
|---|---|---|---|---|
| ORCA | 25 | 64% | +$0.508 | 1.58 |
| KAT | 66 | 64% | +$0.105 | 1.06 |
| AXS | 17 | 71% | -$0.012 | 0.97 |
| HYPER | 18 | 50% | -$0.145 | 0.79 |
HYPER의 PnL -$0.145는 Grid Search 6개 백테 (0.7% / 0.75% / 0.8% / 0.85% / 0.9% / 1.0%) 전체에서 한 자리도 변하지 않았습니다.
Trail 파라미터를 어떻게 바꿔도 HYPER 거래 결과는 동일. 이게 의미하는 건 — HYPER 거래가 트레일링 로직에 닿지도 않고 다른 경로(SL 또는 TIMEOUT)로 끝난다는 것. 어떤 트레이드 활성화 임계값으로도 HYPER에서는 트레일링이 발동조차 안 되고 있었습니다.
HYPER를 제거하면 PnL이 +$0.456 → +$0.601로 32% 자동 개선. 워치리스트에서 즉시 빼야 하는 종목.
30일 — 절벽 너머로 떨어진 진실
여기까지가 7일 데이터로 본 그림입니다. 7일은 표본이 작습니다. 30일로 확장한 결과:
| Trail | 7일 PnL | 30일 PnL | 7일 PF | 30일 PF |
|---|---|---|---|---|
| 0.70% | +$0.282 | -$1.876 | 1.08 | 0.71 |
| 0.75% | +$0.348 | -$1.781 | 1.09 | 0.72 |
| 0.80% | +$0.601 | -$1.649 | 1.20 | 0.74 |
| 0.85% | -$0.227 | -$2.328 | 0.95 | 0.66 |
| 0.90% | -$0.355 | -$2.364 | 0.92 | 0.66 |
모든 Trail 값이 30일에서 손실로 전환.
0.85% 절벽은 살아있습니다 (구조적 패턴). 하지만 7일에서 흑자였던 0.70~0.80% 구간이 30일에선 손실 최소화 영역으로 추락.
종목별로 다시 — ORCA만 살아남는다
30일 종목별 (Trail 0.8%):
| 종목 | 거래 수 | WR | Cum PnL | PF |
|---|---|---|---|---|
| ORCA | 55 | 54.5% | +$0.236 | 1.16 |
| KAT | 144 | 43.8% | -$1.509 | 0.61 |
| AXS | 40 | 45.0% | -$0.376 | 0.61 |
- ORCA는 7일/30일 모두 흑자 (PF 1.58 → 1.16)
- KAT는 7일 +$0.105 → 30일 -$1.509 (180도 반전)
- AXS는 7일/30일 모두 약한 적자
KAT의 7일 흑자가 운이었습니다. 30일이 진실. KAT는 144건 거래에서 PF 0.61, 즉 1달러 벌면 1.6달러 잃는 종목.
무엇을 배웠는가
1. 7일 백테는 결정 근거가 될 수 없다
표본 크기 문제만이 아닙니다. 7일이라는 윈도우 자체가 시장 regime의 한 단면일 뿐입니다. 우리 7일 결과는 KAT가 우연히 좋았던 한 주를 보고 있었습니다. 30일로 확장하니 KAT가 -$1.5을 가져갔습니다.
2. Sweet Spot은 윈도우에 따라 의미가 다르다
Trail 0.8%가 "sweet spot"이라고 말했지만, 7일에선 이익 최적화 지점이고 30일에선 손실 최소화 지점입니다. 같은 값이 같은 의미가 아닙니다.
3. 종목별 PF 게이팅이 핵심이다
Trail 파라미터 튜닝은 부차적이었습니다. 진짜 문제는 종목 선정. ORCA는 모든 Trail 값에서 흑자였고, KAT/AXS는 모든 Trail 값에서 30일 적자였습니다. 어떤 Trail 값을 쓰느냐보다 어떤 종목을 거래하느냐가 PnL의 더 큰 결정 요인.
4. "한 번에 변수 1개" 원칙은 진단을 가능하게 한다
V4.2 → V4.3 → V4.3.1을 거치면서 매번 한 변수씩만 바꿨습니다. 그래서 V4.3에서 PnL이 -$0.29로 떨어졌을 때 정확히 "Trail 1.0%가 너무 높다"고 짚을 수 있었습니다. 만약 V4.2에서 5개 변수를 동시에 바꿨다면 (실제로 V3.8.0이 그렇게 했고 라이브에서 망가졌습니다) 어떤 변경이 망가뜨렸는지 분리할 수 없었을 겁니다.
5. 백테 caveats를 무시하면 안 된다
OpenClaw 백테에는 명시된 한계들이 있었습니다:
- bid_depth 게이트 스킵 (오더북 히스토리 없음) — 상한값 결과
- 같은 캔들에서 TP/SL 동시 hit 시 SL 우선 — 보수적 가정
- 트레일링 peak는 1분봉 기준 — 빠른 wick에서 과대평가
- 슬리피지 0.02% 가정 — 실제 0.01~0.05% 범위
상한값 결과인데도 30일에서 손실이 났다는 건, 라이브에선 더 나쁠 수 있다는 신호.
다음 단계
다음 PoC는 또 한 번에 변수 1개입니다. 검증된 V4.3.1 베이스 위에 추가 필터 한 가지만 얹어서 30일에서 손실이 줄어드는지 확인. 어느 필터를 쓸지, 결과가 어떻게 나올지는 다음 일지에서.
지금 시점에서 확실한 것 — V4.3.1 그대로 라이브 가는 건 없다. 7일 백테가 +$0.601이고 30일 백테가 -$1.65인 전략을 라이브에 올리는 건 표본 위에 운을 거는 것.
받은 영수증을 신뢰합니다. 7일은 운빨이었고, 30일은 더 가까운 진실입니다.