UTC 10:14에 단순한 돌파 전략이 가격이 20분 고점을 돌파한 뒤 암호화폐 무기한 계약을 매수했습니다. 백테스트는 $64,210에 체결된 것으로 나타났습니다. 데이터에 실제로 있던 가격이었고, 신호의 타임스탬프도 정확했으며, 시뮬레이션 주문은 다음 바에 도착했습니다. 우리는 거의 깔끔한 결과라고 결론 내릴 뻔했습니다.
그런 다음 상품 ID를 나란히 맞춰 봤습니다. 신호는 BTCUSDT 무기한 계약에서 나왔고, 체결은 BTCUSD 인버스 계약에서 이뤄졌습니다. 둘 다 $64,210 부근에서 거래됐고 유동성도 충분했습니다. 하지만 서로 다른 호가창이었고, 가격과 틱 크기, 호가 잔량, 수수료 체계도 달랐습니다. 백테스트는 어떤 트레이더도 접근할 수 없는 가상의 시장을 이어 붙인 셈이었습니다.
전략 자체는 특별할 게 없었습니다. 종가가 이동 고점 위로 올라가면 진입하고, 종가가 이동 저점 아래로 내려가면 청산하며, 포지션마다 고정된 달러 위험에 맞춰 규모를 정했습니다. 문제는 “BTC의 가치는 얼마였나?”보다 더 정확한 질문을 던졌을 때에야 드러났습니다. “그 시각에 이 정확한 계약에서 이 주문으로 얼마만큼 매수할 수 있었나?”라고 물었습니다.
전략을 실행하기도 전에 차트는 여러 시장을 합쳐 놓은 상태였다
우리 리서치 피드에서는 거래소별 데이터를 쉽게 비교할 수 있었습니다. 심볼을 정규화하고 통합 가격 시계열을 표시했죠. 시장을 살펴볼 때는 편리했지만, 체결 기준으로는 적절하지 않았습니다. 통합 시계열에는 여러 거래소 중 가장 좋은 가격이 표시될 수 있지만, 전략은 한 거래소에만 주문을 보낼 수 있기 때문입니다.
돌파 시점에 통합 바의 고가는 $64,205였습니다. 선택한 계약의 최근 체결가는 이미 $64,218로 올라 있었습니다. 한편 인버스 계약의 캐시된 호가에는 여전히 $64,210 매도호가가 표시됐습니다. 시뮬레이터는 한 시계열에서 돌파 신호를 가져오고 다른 시계열에서 유리한 매도호가를 가져왔습니다. 각각의 값은 실제였지만, 두 값을 조합한 결과는 허구였습니다.
| 입력 항목 | 백테스트에서 사용한 값 | 주문에 필요한 값 |
|---|---|---|
| 돌파 고점 | 통합 BTC 가격 | 선택한 계약의 가격 이력 |
| 진입 기준 가격 | 캐시된 인버스 계약 매도호가 | 거래 대상 상품의 최신 매도호가 |
| 체결 수량 | 요청한 포지션 규모 | 각 가격 단계에서 매수 가능한 수량 |
시장 데이터 테이블의 한 행은 모든 정보가 갖춰진 것처럼 보여도, 각 필드가 서로 다른 시장을 가리킬 수 있습니다. 심볼 별칭만으로 두 상품이 같은 호가창을 공유한다고 볼 수는 없습니다. 신호 생성부터 주문 실행까지 계약 ID와 거래소, 호가 통화, 타임스탬프를 함께 전달해야 합니다.
호가창을 기준으로 주문을 재생했다
선택한 무기한 계약의 최우선 매도호가와 의사결정 시점에 이용할 수 있었던 호가창 업데이트를 사용해 진입을 다시 실행했습니다. 호가는 최신이었지만 최우선 가격에는 0.18 BTC만 있었습니다. 시뮬레이션 주문은 0.50 BTC였습니다. 나머지 0.32 BTC는 더 높은 매도호가를 소진했을 것입니다.
조정된 진입 가격은 수수료를 제외하고 화면에 표시된 체결가보다 BTC당 $21 높았습니다. 단일 거래로 보면 작은 차이입니다. 하지만 테스트에서 전략의 총수익 대부분은 몇 차례의 빠른 돌파에서 나왔습니다. 해당 진입들을 올바른 호가창 기준으로 재생하자 총수익이 31% 줄었고, taker 수수료와 시장 충격까지 반영하자 더 감소했습니다.
최우선 호가가 신호의 의사결정 시각보다 늦게 도착한 사례도 두 건 발견했습니다. 가장 가까운 타임스탬프를 기준으로 조인하는 백테스트는 자신도 모르게 미래의 업데이트를 선택할 수 있습니다. 이제는 과거 방향으로 조인합니다. 호가는 주문 발송 시점까지 관측된 것이어야 하고, 호가의 경과 시간도 기록합니다. 사용 가능한 최신 호가가 너무 오래됐으면 시뮬레이터는 주문을 체결 불가로 처리하거나 명시적인 오래된 데이터 규칙을 적용합니다.
거래 가능한 가격에 필요한 조건
바 종가는 신호 계산에 유용합니다. 하지만 특정 주문이 그 가격에 체결될 수 있었다는 근거는 되지 않습니다. 이를 판단하려면 가격이 정확히 해당 상품과 거래소에 속해야 하고, 주문 도착 시점에 이용 가능해야 하며, 요청한 수량을 받아줄 만큼 반대편 잔량도 충분해야 합니다. 데이터로 이런 질문에 답할 수 없다면 정직한 결과는 범위나 미체결이지, 꾸며낸 정확한 가격이 아닙니다.
시장 상황을 파악하는 데는 통합 시계열을 계속 사용하되, 체결 경로에서는 제외했습니다. 이제 신호는 선택한 계약 자체의 가격 이력을 참조하고, 주문은 해당 계약의 호가창을 기준으로 재생합니다. 체결가를 계산한 뒤 수수료와 주문 규모를 적용합니다. 손이 조금 더 가지만, 주식 곡선은 훨씬 덜 좋아 보입니다.
그 돌파는 실제로 일어났습니다. 그저 백테스트가 전략이 선택한 시장보다 더 유리한 시장에서 거래한 것으로 처리했을 뿐입니다.
← 전체 글


