OptiNod 아카데미

백테스트와 실전 — 수익 곡선이 갈라지는 다섯 지점

백테스트 수익이 실전 기대 수익이 되지 못하는 이유는 봉 종가에 체결된다는 가정에서 시작합니다. 신호와 체결 사이의 지연을 다섯 지점으로 분해합니다.

> 백테스트 곡선과 실전 곡선이 갈라지는 출발점은 봉 종가에 체결된다는 가정입니다. 신호와 체결 사이의 한 칸 지연이 어디서 비용으로 바뀌는지를 다섯 지점에서 짚어 봅니다.

백테스트는 과거 데이터에 전략 규칙을 그대로 돌려 가상의 수익 곡선을 만드는 작업입니다. 규칙이 명확하고 데이터가 깨끗하면 누구나 같은 곡선을 다시 그릴 수 있습니다. 이렇게 다시 그릴 수 있다는 점 덕분에 백테스트는 전략을 검증하는 1차 도구로 자리 잡았습니다.

문제는 대부분의 사람이 이 곡선을 실전 기대 수익으로 바로 읽는다는 데 있습니다. 백테스트 연수익률이 80%로 나오면 실전에서도 비슷한 수익을 기대하고, 그 차이가 벌어지면 전략이 틀렸다고 판단합니다. 그러나 전략 규칙은 그대로인데 곡선만 갈라지는 경우가 대부분입니다. 곡선이 갈라지는 원인은 규칙이 전제하는 가정에 있습니다.

가장 큰 가정은 봉 종가에 체결된다는 것입니다. 백테스트 엔진은 신호가 뜬 봉의 종가를 진입 가격으로 기록합니다. 그러나 실전에서 신호는 봉이 마감된 뒤에야 확정되고, 주문은 다음 봉에서 체결됩니다. 그 사이 가격은 이미 움직여 있습니다. 이 한 칸의 지연이 슬리피지, 수수료, 데이터 해상도, 생존 편향과 맞물리면서 시간이 갈수록 두 곡선을 벌려 놓습니다. 이 글은 그 다섯 지점을 하나씩 짚어 봅니다.

같은 지점에서 출발한 백테스트 곡선과 실전 곡선이 시간이 지날수록 벌어집니다

신호는 봉 마감에 뜨지만 체결은 다음 봉입니다

백테스트가 전제하는 첫 가정은 신호가 뜬 봉의 종가에 그 가격으로 체결된다는 것입니다. 종가 기준 돌파, 종가 기준 이동평균 교차처럼 종가를 트리거로 쓰는 전략은 거의 전부 이 가정을 깔고 있습니다. 그러나 종가는 봉이 마감되는 순간 확정되는 값입니다. 그 순간이 지나야 신호가 나오고, 실제 주문은 다음 봉에서 체결됩니다. 백테스트가 진입 가격으로 기록한 종가는 실전에서 체결할 수 없는 가격입니다.

평온한 구간에서는 이 지연이 작습니다. 봉과 봉 사이 가격이 거의 움직이지 않으면 종가와 다음 봉 시가가 비슷하기 때문입니다. 지연이 비용으로 바뀌는 경우는 변동성이 큰 봉입니다.

2024년 8월 5일 BTC 일봉이 이 차이를 선명하게 보여줍니다. 8월 4일 일봉 종가는 58,161달러였습니다. 종가 기준 진입 신호가 이 자리에서 켜졌다면 백테스트는 진입 가격을 58,161달러로 기록합니다. 그러나 실전에서 그 신호는 8월 4일 봉이 마감된 뒤에야 확정되고, 주문은 8월 5일 봉에서 체결됩니다. 8월 5일 봉은 58,161달러에 시작해 같은 날 49,000달러까지 떨어졌습니다. 시가에서 저가까지 약 15.7% 하락입니다. 백테스트는 58,161달러에 들어가 종가 54,019달러로 마감하는 거래로 기록하지만, 실전 매수 주문은 다음 봉 시가에 체결된 직후 깊은 손실 구간에 들어갑니다.

종가 체결 가정의 허점은 추세 추종 전략에서 특히 큽니다. 추세 추종은 가격이 크게 움직인 봉의 종가에 신호가 나오는 구조라, 신호와 체결 사이에 가격이 이미 한참 움직여 있을 확률이 높습니다. 신호 봉에서 가격이 많이 움직였다는 사실 자체가 다음 봉에서도 움직일 가능성을 높입니다. 종가 체결을 가정한 백테스트가 가장 낙관적으로 부풀려지는 곳이 바로 추세 추종 진입입니다.

신호는 봉 마감에 확정되고 체결은 다음 봉이라 그 사이에 진입가가 벌어집니다

슬리피지는 변동성 구간에서 비선형으로 커집니다

슬리피지(Slippage)는 주문을 낸 가격과 실제 체결된 가격의 차이입니다. 시장가 주문은 호가창의 여러 단계를 훑으며 체결되고, 그 평균 체결가는 주문 직전 호가보다 불리합니다. 백테스트가 단일 가격에 전량 체결된다고 가정하는 동안, 실전 주문은 호가창의 윗단계까지 먹으며 채워집니다.

유동성이 풍부한 BTC 현물에서 작은 시장가 주문의 슬리피지는 보통 몇 bp(베이시스 포인트, 1bp는 0.01%) 정도입니다. 이 정도면 백테스트와 실전의 차이가 거의 느껴지지 않습니다. 슬리피지가 비선형으로 커지는 자리는 변동성이 크게 확대되는 구간과 갭입니다.

다시 8월 5일 BTC를 시간 단위로 보면 이 차이가 분명해집니다. 8월 5일 06:00 시간봉은 52,718달러에 시작해 한 시간 안에 49,000달러까지 떨어졌다가 51,588달러로 마감했습니다. 한 시간 안의 고저 폭이 약 4,000달러입니다. 호가창이 순식간에 얇아져 의도한 가격보다 한참 아래에서 체결됩니다. 백테스트가 손절을 52,000달러 한 점에 체결한 것으로 기록하는 동안, 실전 체결가는 50,000달러 부근까지 밀릴 수 있습니다. 변동성이 클수록 호가창이 얇아지고, 호가창이 얇을수록 슬리피지가 다시 커지는 식으로 비용이 더 커집니다.

슬리피지를 0으로 둔 백테스트는 이렇게 커지는 비용을 통째로 빼버립니다. 평온한 구간의 거래가 대부분이면 0 슬리피지 가정도 큰 오차를 내지 않지만, 전략의 수익이 변동성 구간의 큰 거래 몇 건에서 나온다면 슬리피지를 0으로 둔 백테스트는 실전과 가장 크게 갈라집니다. 슬리피지는 변동성에 따라 달라지는 비용으로 봐야 합니다. 평균값 하나로만 잡으면 변동성 구간에서 실제로 치르는 큰 비용을 통째로 놓칩니다.

수수료와 펀딩은 거래 빈도에 비례해 누적됩니다

수수료는 한 거래만 놓고 보면 작습니다. 거래소 테이커 수수료는 통상 거래대금의 0.04%에서 0.1% 사이입니다. 한 번 진입하고 한 번 청산하면 왕복 0.08%에서 0.2% 정도입니다. 단일 거래만 보면 무시해도 될 만한 크기로 보입니다. 쌓이는 게 문제입니다.

하루에 다섯 번 매매하는 단타 전략을 가정하겠습니다. 왕복 수수료가 0.1%라면 하루 다섯 거래로 0.5%, 한 달 20거래일이면 약 10%가 수수료로 빠져나갑니다. 1년이면 100%를 넘습니다. 백테스트에서 수수료를 0으로 두면 이 100%가 그대로 수익으로 남지만, 실전에서는 계좌에서 그만큼이 차감됩니다. 거래 빈도가 높은 전략일수록 수수료를 0으로 둔 백테스트와 실전 곡선이 가파르게 벌어집니다.

선물 포지션에는 펀딩(Funding)이 더해집니다. 무기한 선물은 8시간마다 펀딩을 주고받는데, 롱이 우세한 시장에서는 롱 포지션이 숏에게 펀딩을 지불합니다. 2024년 8월 초 BTC 무기한 선물의 펀딩은 8시간마다 약 0.01% 안팎이었습니다. 하루 세 번이면 약 0.03%, 한 달이면 약 0.9%입니다. 포지션을 길게 들고 가는 추세 추종 전략이 이 펀딩을 백테스트에 넣지 않으면 보유 기간이 길수록 실전 곡선이 더 내려갑니다.

수수료와 펀딩은 한 거래에서는 잘 보이지 않다가 거래가 쌓이면 비로소 눈에 띄는 비용입니다. 백테스트의 연수익률이 높아도 거래 빈도가 높으면 실전 순수익은 크게 줄어듭니다. 거래 빈도를 줄이면 신호 수가 줄어 통계적 신뢰도가 낮아지는 맞바꿈이 생기므로, 빈도와 거래당 기대 수익을 함께 봐야 합니다. 수수료를 떼고도 남는 기대 수익이 있어야 실전에서 의미가 있습니다.

거래당 작은 수수료가 거래 빈도에 비례해 수익을 갉아먹습니다

봉 종가 백테스트는 봉 내부의 경로를 모릅니다

일봉 종가 데이터로 돌리는 백테스트는 각 봉을 시가·고가·저가·종가 네 값으로만 봅니다. 봉 안에서 가격이 어떤 순서로 움직였는지는 데이터에 담겨 있지 않습니다. 이 데이터 해상도의 한계가 손절과 익절을 동시에 둔 전략에서 결정적인 오차를 낳습니다.

한 봉의 고가가 익절 가격에 닿고 저가가 손절 가격에 닿았다고 하겠습니다. 두 가격이 모두 한 봉 안에서 도달됐다면, 실전 결과는 둘 중 어느 쪽이 먼저 닿았느냐로 갈립니다. 익절이 먼저 닿으면 이익으로 청산되고, 손절이 먼저 닿으면 손실로 청산됩니다. 그러나 일봉 데이터는 고가와 저가의 도달 순서를 담고 있지 않습니다. 백테스트 엔진은 이 경우 한쪽으로 정해진 가정을 따르는데, 손절을 먼저 가정하는 보수적인 기본값을 쓰는 엔진도 많습니다. 어느 쪽으로 가정하든 실제 도달 순서와 다를 수 있습니다.

8월 5일 BTC 일봉이 이 문제를 그대로 보여줍니다. 일봉은 58,161달러에 시작해 고가 58,306달러, 저가 49,000달러, 종가 54,019달러로 마감했습니다. 시간 단위로 쪼개 보면 가격은 장 시작 직후 고가 58,306달러를 기록하고, 그 뒤 06:00까지 줄곧 흘러내려 49,000달러까지 떨어졌습니다. 만약 시가 58,161달러에 들어가 익절을 58,300달러, 손절을 50,000달러에 둔 롱 포지션이 있었다면, 익절과 손절이 모두 이 한 봉 안에서 닿습니다. 손절을 먼저 가정하는 백테스트는 이 거래를 손실로 처리합니다. 그러나 실제 경로는 장 시작 직후 58,306달러에 먼저 도달했으므로 익절 58,300달러가 먼저 닿아 이익으로 청산됩니다. 같은 봉에 같은 두 가격인데 백테스트는 손실로, 실전은 이익으로 처리됩니다. 도달 순서를 모르는 백테스트는 이 거래의 손익을 거꾸로 기록합니다.

이 오차를 줄이려면 백테스트 데이터의 해상도를 진입 봉보다 한 단계 더 잘게 잡아야 합니다. 일봉 전략이라도 손절·익절 처리는 시간봉이나 분봉 데이터로 봉 내부 경로를 확인하는 방식이 실전에 가깝습니다. 봉 내부 경로를 모르는 백테스트는 손절과 익절이 한 봉 안에서 만나는 거래에서 가장 크게 틀립니다.

한 봉 안에서 익절과 손절에 모두 닿을 때 도달 순서가 손익 부호를 가릅니다

생존 편향과 룩어헤드는 곡선을 위로 부풀립니다

앞의 네 지점이 실전 곡선을 아래로 끌어내리는 비용이라면, 생존 편향(Survivorship Bias)과 룩어헤드(Look-ahead Bias)는 백테스트 곡선을 위로 부풀리는 왜곡입니다. 앞의 비용은 실전에서야 나타나고, 이 두 왜곡은 백테스트 단계에서 이미 들어가 있어 더 찾아내기 어렵습니다.

생존 편향은 지금 살아남은 종목만으로 검증할 때 생깁니다. 알트코인 추세 전략을 검증한다면서 지금 시점에 거래되는 상위 100개 코인만 데이터로 쓰면, 그 100개는 이미 살아남은 종목입니다. 같은 기간 상장 폐지되거나 가치가 사라진 수백 개 코인은 데이터에서 빠집니다. 백테스트는 살아남은 종목의 상승만 반영하고 사라진 종목의 손실은 담지 못합니다. 과거에 잘 오른 알트만 골라 검증하면 거의 모든 전략이 좋은 곡선을 그립니다. 실전에서는 어느 코인이 살아남을지 미리 알 수 없으므로, 생존 편향이 들어간 백테스트는 실전과 처음부터 다른 종목 집단을 다룹니다.

룩어헤드는 미래 데이터가 과거 시점의 판단에 끼어들 때 생깁니다. 흔한 사례는 봉 마감 전에 종가를 쓰는 것입니다. 진행 중인 봉의 아직 확정되지 않은 종가로 신호를 계산하면, 실전에서는 알 수 없는 값을 백테스트가 미리 가져다 쓰는 셈입니다. 지표 계산에 미래 봉을 포함하거나, 데이터 정규화에 전체 기간의 통계를 쓰는 것도 같은 종류의 누수입니다. 룩어헤드가 들어간 백테스트는 미래를 일부 보고 결정하므로 현실에서는 나올 수 없는 매끄러운 곡선을 그립니다.

두 왜곡이 더 위험한 이유는 비용을 빠뜨린 경우와 달리 곡선을 오히려 좋아 보이게 만든다는 데 있습니다. 슬리피지나 수수료를 빠뜨린 백테스트는 실전에서 곧 실망으로 이어지지만, 생존 편향과 룩어헤드가 들어간 백테스트는 검증 단계에서 좋은 성적을 내며 자신감을 키웁니다. 그 자신감만 믿고 실전 자금을 넣은 뒤에야 곡선이 갈라집니다. 백테스트를 믿기 전에 데이터에 어떤 종목이 들어갔는지, 미래 값이 새지 않았는지부터 의심해야 합니다.

살아남은 종목만 검증에 들어가고 사라진 종목의 손실은 데이터에서 빠집니다

현실적인 백테스트 설정을 점검하는 체크리스트

위 다섯 지점을 백테스트 설정에 반영하면 실전 곡선과의 간격을 좁힐 수 있습니다. 다음 항목을 백테스트를 돌리기 전에 확인합니다.

  • [ ] 체결 시점: 진입·청산을 다음 봉의 시가로 처리합니다. 신호 봉의 종가를 진입 가격으로 쓰지 않습니다. 종가 트리거 전략이라면 다음 봉 시가 체결을 기본값으로 둡니다.
  • [ ] 슬리피지: 거래당 최소 5bp 이상을 비용으로 넣고, 변동성이 큰 거래에는 더 높은 슬리피지를 적용합니다. 슬리피지 0 설정은 쓰지 않습니다.
  • [ ] 수수료·펀딩: 왕복 수수료를 거래소 테이커 기준(통상 0.08%~0.2%)으로 넣습니다. 선물이면 8시간 펀딩(예: 0.01% 안팎)을 보유 기간에 비례해 차감합니다.
  • [ ] 데이터 해상도: 손절·익절을 함께 둔 전략은 진입 봉보다 한 단계 잘게(일봉 전략이면 시간봉 이하) 봉 내부 경로를 확인해 도달 순서를 처리합니다.
  • [ ] 모집단: 상장 폐지·소멸 종목을 포함한 당시 시점 그대로의 종목 집합으로 검증합니다. 지금 살아남은 종목만으로 검증하지 않습니다.
  • [ ] 시점 처리: 모든 신호 계산이 마감된 봉의 확정값만 쓰는지, 미래 봉이나 전체 기간 통계가 새어 들어가지 않았는지 확인합니다.

이 여섯 항목을 모두 반영한 백테스트의 수익률은 0 비용으로 돌린 곡선보다 낮게 나옵니다. 낮아진 그 곡선이 실전 기대 수익에 더 가깝습니다.

백테스트와 실전을 나란히 추적하면 갈라짐의 원인을 좁힙니다

현실적인 설정으로 백테스트를 돌렸어도 실전과 완전히 일치하지는 않습니다. 남은 차이의 원인을 좁히려면 실전 거래를 시작한 뒤 같은 기간의 백테스트 곡선과 실전 곡선을 나란히 비교합니다. 두 곡선이 갈라지는 거래를 하나씩 들여다보면 어느 지점에서 가정이 깨졌는지 보입니다.

진입 가격 차이가 크면 체결 시점이나 슬리피지 문제입니다. 손절·익절 거래에서 결과가 뒤집혔다면 봉 내부 경로 문제입니다. 누적 비용이 예상보다 크면 수수료·펀딩을 적게 잡은 것입니다. 갈라짐을 거래 단위로 따라가면 다섯 지점 중 어느 것이 가장 크게 작용했는지 좁힐 수 있고, 그 지점을 백테스트 설정에 다시 반영해 곡선을 실전에 가깝게 다듬어 갑니다.

백테스트는 전략의 방향성을 검증하는 도구입니다. 실전 수익을 미리 알려 주지는 못합니다. 종가에 체결된다는 가정을 의심하는 데서 시작해 슬리피지, 수수료, 데이터 해상도, 생존 편향과 룩어헤드까지 점검하면, 백테스트 곡선은 자신감만 부풀리던 곡선에서 실전을 가늠하는 도구로 바뀝니다. 두 곡선이 왜 갈라지는지 설명할 수 있을 때, 비로소 백테스트의 숫자를 실전 판단에 쓸 수 있습니다.