#03 백테스트와 라이브의 간극을 줄인 트레일링 스탑 개선 기록

백테스트와 라이브의 간극을 줄인 트레일링 스탑 개선 기록

최근 HMA 기반 ETHUSDT 전략을 다듬으면서 가장 크게 느낀 문제는 하나였다. 백테스트에서는 좋아 보이는데, 라이브 엔진의 실제 동작과는 미묘하게 다른 부분이 있었다는 점이다. 특히 트레일링 스탑이 언제부터 1분봉 기준으로 더 촘촘하게 움직이는지가 핵심이었다.

이번 작업의 목표는 단순히 성과를 높이는 것이 아니라, 백테스트와 라이브가 가능한 한 같은 규칙으로 움직이도록 맞추는 것이었다. 그 과정에서 여러 후보 아이디어를 실험했고, 결국 남긴 것과 버린 것이 꽤 분명해졌다.

문제의 출발점

기존 구조에서는 트레일링 스탑이 1분봉 기준으로 항상 켜져 있는 백테스트 해석이 가능했다. 하지만 라이브 엔진은 그렇게 동작하지 않는다. 라이브에서는 일정 수익 구간에 들어가기 전까지는 30분봉 기준으로 움직이고, 이후에야 1분봉 보호 루프를 켠다.

겉으로 보면 둘 다 같은 적응형 트레일링처럼 보일 수 있다. 하지만 실제로는 차이가 크다.

  • 항상 1분봉을 쓰면 진입 초반부터 스탑이 더 자주 올라간다.
  • 라이브처럼 profit gate 이후에만 1분봉을 쓰면 초반에는 더 넓게 버틴다.
  • 결국 같은 전략처럼 보여도 손익 곡선과 청산 구조가 달라진다.

실험한 후보들

트레일링 스탑 v2 아이디어는 처음에 꽤 크게 출발했다. 설계 문서 기준으로는 아래 네 가지 축을 단계적으로 실험했다.

  1. Giveback Stop
  2. Hybrid Anchor
  3. Regime 기반 전환
  4. 조건부 1분봉 활성화

처음에는 이 기능들이 서로 시너지를 낼 수 있을 거라 생각했다. 하지만 백테스트를 쪼개서 확인해보니 결론은 예상보다 단순했다.

  • Giveback Stop은 보조 가드레일로는 흥미로웠지만 기본 채택 수준은 아니었다.
  • Hybrid Anchor는 구조적으로는 좋았지만 결과 우위가 뚜렷하지 않았다.
  • Regime가 메인 trailing 성격을 직접 바꾸는 구조는 성능이 좋지 않았다.
  • 실제로 끝까지 남은 건 라이브 엔진과 맞춘 profit_mid 기반 30분봉→1분봉 전환 로직이었다.

최종적으로 채택한 방식

최종 채택안은 복잡한 상태 머신이 아니라, 오히려 더 현실적인 정합성 확보였다.

핵심은 이렇다.

  • 포지션 진입 후 초반에는 30분봉 기준 trailing을 사용한다.
  • adaptive_trail_profit_mid를 넘긴 뒤부터는 다음 30분 구간에서 1분봉 trailing을 활성화한다.
  • 한 번 1분봉 trailing이 켜지면 포지션 종료까지 유지한다.
  • profit 판정은 라이브 엔진과 동일하게 close가 아니라 high/low 기준도 반영할 수 있게 맞췄다.

이 방식은 “가장 높은 손익”만 노린 해법은 아니었다. 대신 백테스트가 라이브보다 과하게 유리해 보이던 왜곡을 줄이는 방향이라는 점에서 훨씬 의미가 있었다.

파라미터 튜닝 결과

기본 구조를 맞춘 뒤에는 live-like 조건에서 트레일링 파라미터를 다시 스윕했다. 좁은 범위로 여러 조합을 돌린 뒤, 학습 구간과 검증 구간을 분리해서 과최적화를 걸러냈다.

최종 추천값은 아래 조합이었다.

  • use_profit_mid_trailing_1m_activation = true
  • adaptive_trail_mult_wide = 4.5
  • adaptive_trail_profit_mid = 1.0
  • adaptive_trail_profit_tight = 2.0
  • adaptive_trail_profit_basis = "hl"

검증 구간 기준으로는 이 조합이 수익성과 안정성 균형이 가장 나았다. 더 공격적인 조합도 있었지만, 낙폭이 너무 커서 채택하지 않았다.

최신 백테스트 결과

현재 메인 브랜치 기준 기본 설정으로 다시 돌린 결과는 아래와 같다.

  • 기간: 2024-01-01 ~ latest
  • 초기 자산: $1,100
  • 총 손익: +$6,994.60
  • 최대 낙폭: -33.66%
  • Profit Factor: 1.26
  • 총 트레이드 수: 2021
  • 승률: 42.1%

특히 눈여겨본 건 트레일링 청산의 품질이었다.

  • Trailing Stop 청산: 878건
  • 평균 Exit_R: +1.343R
  • 평균 Capture%: 50.9%
  • 평균 Giveback_R: 1.003R
  • 청산 후 6봉 내 추가 추세가 1R 이상 더 간 비율: 30.1%

완벽한 숫자는 아니다. 하지만 중요한 건 이제 이 결과가 “백테스트만의 환상”이 아니라, 라이브 엔진의 실제 스위칭 방식과 훨씬 더 가까운 해석 위에서 나온다는 점이다.

이번 작업에서 얻은 교훈

이번 개선 작업에서 가장 크게 배운 건 두 가지다.

  1. 복잡한 기능을 많이 붙인다고 성과가 좋아지지는 않는다.
    Giveback, Hybrid Anchor, Regime 같은 아이디어는 각각 의미가 있었지만, 실제 채택 단계까지 간 것은 아니었다.
  2. 백테스트와 라이브의 정합성이 생각보다 더 중요하다.
    같은 전략이라도 실행 타이밍과 해상도가 다르면 결과 해석 자체가 달라진다.

결국 남긴 것은 가장 화려한 기능이 아니라, 가장 실전적인 기능이었다. 전략 개발에서 종종 놓치기 쉬운 부분이지만, 실제 운영을 생각하면 이런 선택이 훨씬 중요하다.

마무리

이번 작업은 “새 기능을 많이 넣었다”기보다는, 불필요한 가설을 지우고, 남겨야 할 하나를 분명하게 남긴 과정에 가까웠다.

앞으로도 이 전략을 개선할 때는 같은 기준을 유지하려 한다.

  • 먼저 백테스트와 라이브의 차이를 확인하고
  • 기능은 단계적으로 쪼개서 검증하고
  • 최종 채택은 수익뿐 아니라 정합성과 운영 가능성까지 포함해 판단한다

다음 글에서는 이번에 만들었던 트레일링 효율 분석 지표들, 예를 들면 Capture%, Giveback_R, PostExit 추적치가 실제로 어떤 의사결정에 도움이 됐는지도 정리해볼 생각이다.

댓글 남기기