Jesse 백테스트를 믿기 전에 반드시 확인해야 할 함정 5가지

저는 처음 Jesse로 백테스트를 돌렸을 때 결과가 너무 좋아서 바로 실전에 붙였습니다. 그리고 첫 달 결과를 보고 조용히 봇을 껐습니다. 백테스트 수익 곡선과 실전 결과 사이의 괴리는 단순한 시장 변동성 문제가 아니었습니다. 코드 설정과 데이터 처리 방식 자체에 구조적인 함정이 숨어 있었습니다. 이번 칼럼에서는 제가 직접 겪으면서 하나씩 발견한 Jesse 백테스트의 대표적인 함정 5가지를 정리합니다. 이 글을 읽는 분이 저와 같은 시행착오를 반복하지 않길 바랍니다.

함정 1·2: 데이터와 타이밍이 결과를 만든다

첫 번째 함정은 룩어헤드 바이어스입니다. Jesse에서 캔들 데이터를 참조할 때 self.candles 또는 self.close 를 잘못 인덱싱하면 현재 미완성 봉의 값을 조건 판단에 사용하게 됩니다. 예를 들어 4시간봉 전략에서 현재 봉이 아직 닫히지 않은 상태에서 그 봉의 종가를 기준으로 진입 조건을 평가하면, 백테스트는 미래 정보를 사용하는 것과 같습니다. 실전에서는 절대 일어날 수 없는 타이밍에 진입이 기록되면서 승률이 비현실적으로 높아집니다. 저는 self.candles[-1] 과 self.candles[-2] 를 혼용하다가 이 문제를 만났습니다. 현재 닫힌 봉은 반드시 인덱스 -2로 참조해야 합니다. 두 번째 함정은 슬리피지와 수수료 설정 누락입니다. Jesse 백테스트 설정 파일에서 fee_rate 와 slippage 를 기본값 0으로 두는 경우가 많습니다. 바이낸스 선물 기준 메이커 수수료는 0.02%, 테이커는 0.05%이고, 변동성이 높은 구간에서는 슬리피지가 0.1% 이상 발생합니다. 이 값을 0으로 설정한 채 백테스트를 돌리면 고빈도 전략일수록 실제보다 훨씬 좋은 결과가 나옵니다. config.py 에서 fee_rate 를 최소 0.0005로, slippage 를 0.001 이상으로 설정해두는 것이 현실에 가까운 시뮬레이션의 출발점입니다.

함정 3·4: 데이터 기간과 포지션 사이징의 착시

세 번째 함정은 샘플 기간 편향입니다. Jesse로 백테스트를 처음 돌릴 때 가장 쉽게 접근할 수 있는 기간은 2020~2021년 강세장 구간입니다. 이 구간은 거의 모든 롱 전략이 좋은 결과를 냅니다. 문제는 이 기간만으로 전략을 검증하고 실전에 투입하는 경우입니다. 저는 2022~2023년 횡보·하락 구간을 포함해 다시 돌렸을 때 동일 전략의 MDD가 예상보다 두 배 이상 커지는 것을 확인했습니다. Jesse CLI에서 백테스트 기간을 설정할 때 jesse run –start-date 2020-01-01 처럼 강세장만 포함하지 말고, 반드시 약세장과 횡보 구간이 모두 포함된 최소 3년 이상의 데이터로 검증해야 합니다. 네 번째 함정은 고정 포지션 사이징으로 인한 수익 곡선 왜곡입니다. Jesse 기본 예제 코드에는 self.position_size 를 고정값으로 설정하는 패턴이 많습니다. 예를 들어 매 진입마다 잔고의 100%를 베팅하도록 설정된 경우, 초기 자본이 작을 때는 수익이 크게 보이지만 실전에서 켈리 기준이나 리스크 퍼센트 기반 사이징으로 전환하면 수익 곡선이 완전히 달라집니다. 저는 포지션 사이징을 self.balance * risk_per_trade / stop_loss_distance 공식으로 동적 계산하도록 변경한 이후 백테스트와 실전 결과의 괴리가 줄어드는 것을 관찰 중입니다.

함정 5와 실전 적용: 최적화 과적합의 덫에서 빠져나오기

다섯 번째이자 가장 조심해야 할 함정은 파라미터 과적합입니다. Jesse에는 jesse-optuna 또는 직접 구현한 그리드서치로 파라미터를 최적화하는 기능이 있습니다. EMA 기간을 9~200 범위에서 탐색하거나, RSI 임계값을 30~70에서 1 단위로 조정하다 보면 특정 역사적 구간에서 완벽하게 들어맞는 파라미터 조합을 발견하게 됩니다. 이것이 바로 커브 피팅입니다. 과거 데이터에 최적화된 파라미터는 새로운 데이터에서 무너질 가능성이 높습니다. 저는 이 문제를 다루기 위해 워크포워드 테스트를 직접 구현했습니다. 전체 데이터를 인샘플(최적화 구간) 70%와 아웃오브샘플(검증 구간) 30%로 나눈 뒤, 인샘플에서 찾은 파라미터를 아웃오브샘플에서 한 번 더 돌립니다. 두 구간의 결과 차이가 클수록 과적합 가능성이 높습니다. Jesse에서 이를 구현하는 가장 단순한 방법은 –start-date 와 –finish-date 를 스크립트로 분리해 두 번 실행하고 결과를 비교하는 것입니다. 실전 투입 전에 이 단계를 거치지 않은 전략은 검증 중 상태로 간주하고 있습니다. 이 다섯 가지 함정을 모두 점검한 전략만이 실전 테스트 자격이 있다고 생각합니다.

💬 운영자 한마디

저는 지금도 새 전략을 짤 때마다 이 체크리스트를 처음부터 다시 돌립니다. 경험이 쌓여도 실수는 반복됩니다. 백테스트 결과가 좋을수록 더 의심하는 습관이 실전 손실을 줄여줬습니다. 확신보다 검증이 먼저입니다.

— J_River · autoprofit 운영자

✅ 이번 주 체크리스트

  • 캔들 인덱스 확인: 진입 조건에 self.candles[-2] 를 사용하는지 반드시 확인
  • 수수료 설정: config.py 에서 fee_rate 0.0005 이상, slippage 0.001 이상 적용
  • 백테스트 기간: 강세·횡보·약세 구간이 모두 포함된 3년 이상 데이터로 검증
  • 포지션 사이징: 고정값 대신 잔고 대비 리스크 퍼센트 기반 동적 계산 방식 적용
  • 워크포워드 테스트: 인샘플 70% 최적화 후 아웃오브샘플 30%에서 재검증 필수
  • 파라미터 범위 제한: 탐색 범위를 최소화하고 최적화 횟수를 기록으로 남기기
  • 실전 투입 전 소액 라이브 테스트: 백테스트 통과 전략도 최소 2주 소액 운영 후 평가

Jesse는 강력한 도구지만, 도구를 믿는 것과 결과를 믿는 것은 다릅니다. 오늘 소개한 5가지 함정을 하나씩 점검하고 나면, 백테스트 결과를 다르게 읽게 될 것입니다.

※ 본 콘텐츠는 운영자 개인의 경험과 연구를 바탕으로 한 정보 제공 목적이며, 특정 종목에 대한 투자 권유나 매매 시그널이 아닙니다. 암호화폐 및 자동매매는 원금 손실 가능성이 있는 고위험 활동이며, 모든 투자 판단과 그 결과에 대한 책임은 투자자 본인에게 있습니다.