백테스트가 내게 거짓말한 밤

어느 날 밤, 백테스트는 내가 변변찮은 시작 잔고를 2,792조 원으로 불렸다고 알려줬다 — 지구상 대부분 경제권의 연간 생산량을 넘어서는 액수다. 나는 그것을 멍하니 바라봤다. 몇 분 동안, 내 안의 조용하고 탐욕스러운 한 부분이 그게 진짜일 수도 있다는 이유를 찾아 나섰다.

진짜가 아니었다. 버그였다. 그리고 그 버그는 어떤 승리 전략보다도 더 많은 것을 가르쳐줬다. 왜냐하면 그것은 백테스트가 존재하는 단 하나의 이유, 즉 현실을 존중하는 일에 관한 버그였기 때문이다.

나를 겁먹게 했어야 할 숫자

나는 파라미터 탐색을 돌리고 있었다 — 수천 개의 설정(config) 각각을 과거 데이터 전체에 걸쳐 재현하고 최종 결과로 순위를 매기는 작업이었다. 대부분은 평범하게 돌아왔다. 하나는 미쳐 있었다.

당신에게 유리한 방향으로 미친 결과는 시스템이 내놓을 수 있는 가장 위험한 산출물이다. 왜냐하면 그것은 성공의 얼굴을 하고 도착하기 때문이다. 손실을 낸 실행은 당신을 디버깅하게 만든다. “잘 되는” 실행은 당신을 축하하게 만든다. 검증은 비대칭적이고, 정확히 잘못된 방향으로 흐른다. 우리는 싫어하는 결과는 심문하고, 좋아하는 결과는 그냥 통과시킨다. 나도 이걸 거의 그냥 통과시킬 뻔했다.

내가 — 어렵게 — 배워야 했던 본능은 그 반대다. 결과가 더 화려할수록, 무언가 망가졌다는 것이 더 확실하다. 시장은 처음 시스템을 만드는 사람에게 작은 나라의 GDP를 건네주지 않는다. 당신의 시뮬레이션이 그렇다고 말한다면, 그 시뮬레이션은 거짓말을 하고 있는 것이고, 당신의 유일한 임무는 어떻게 그런 거짓말을 했는지 알아내는 것이다.

첫 번째 실수: 매번 계좌 전체를 거는 것

첫 번째 결함은 포지션 사이징에 있었다. 각 거래는 사실상 계좌 전체 규모로 잡혔고, 수익은 곧장 다음 베팅으로 복리되어 들어갔다. 그 순간, 당신은 트레이딩을 모델링하기를 멈추고 기하급수를 모델링하기 시작한다. 충분히 긴 실행이라면 아주 약간만 유리한 결과의 연속 — 혹은 우연히 충분히 자주 올바른 방향으로 깨지는 순수한 노이즈 — 만으로도, 그것은 성장하는 게 아니라 폭발한다. 수학은 현실에서 도망쳐서 다시는 뒤돌아보지 않는다.

이것이 완전 복리 백테스트의 유혹적인 점이다. 그것은 멋진 숫자를 만들어내는 데 좋은 전략이 필요하지 않다. 그저 충분히 많은 거래와, 베팅이 계속 굴러가도록 내버려둘 만큼 후한 시뮬레이터만 있으면 된다. 복리는 희미하고 무의미한 통계적 기울기를 지수 곡선으로 바꾸고, 수천 번의 거래에 걸친 지수 곡선은 운명처럼 보이지만 아무 의미도 없는 숫자를 만들어낸다. 그 천문학적인 잔고는 엣지의 증거가 아니었다. 그것은 무작위성에 적용된 계좌 전체 노출의 증거였다.

두 번째 실수: 죽을 수 없는 시뮬레이터

두 번째 결함은 더 나빴다. 왜냐하면 그것은 철학적인 문제였기 때문이다. 내 백테스터에는 흡수 장벽 — 계좌가 그냥 죽는 지점 — 이 없었다. 그래서 나쁜 거래의 연속이 잔고를 99.99% 끌어내렸을 때, 시뮬레이션은 멈추지 않았다. 그것은 시체를 테이블 위에 그대로 두고 계속 거래하게 했다. 그리고 그 거의 0에 가까운 잔고에서, 운 좋은 연승이 계좌를 “되살려” 터무니없는 높이까지 다시 끌어올렸다.

실제 계좌에서 그런 회복은 불가능하다. 0은 0이다. 청산된 잔고에는 두 번째 막이 주어지지 않는다 — 당신은 영구적으로 게임에서 퇴출되고, 어떤 미래의 연승도 시간을 거슬러 올라가 당신을 구할 수 없다. 파산한 계좌가 계속 거래하도록 내버려둠으로써, 내 코드는 모든 트레이딩에서 가장 중요한 규칙을 조용히 삭제해버렸다. 즉, 파멸은 최종적이라는 규칙이다. 그 아래로 흐르는 모든 것 — 그 환상 전체 — 은 단 하나의 빠진 제약에서 논리적으로 따라 나왔다. 그 시뮬레이션은 살아남은 전략을 모델링하고 있던 게 아니었다. 그것은 죽도록 허용된, 그리고 죽은 채로 남아 있는 것은 금지된 전략을 모델링하고 있었다.

옵티마이저는 내 사각지대를 사냥하고 있었다

여기 내가 이해하는 데 가장 오래 걸린 부분이 있다. 파라미터 탐색은 그 터무니없는 설정에 우연히 걸려 넘어진 게 아니었다. 그것은 그것을 찾아 나섰던 것이다.

수천 개의 설정에 대한 탐색은 중립적인 관찰자가 아니다. 그것은 당신이 건네준 어떤 지표든 그것에 맞춰 최적화하는 적수다. 당신의 지표가 “최종 잔고”이고 당신의 시뮬레이터에 약점 — 비현실적인 일들이 조용히 허용되는 지점 — 이 있다면, 탐색은 그 약점을 찾아내 자신의 모든 무게로 그곳에 기댈 것이다. 그것은 최고의 전략에 보상하지 않는다. 그것은 당신의 시뮬레이션과 현실 사이의 틈을 가장 효율적으로 착취하는 설정에 보상한다.

그래서 그 조 단위의 결과는 무작위로 떠오른 하나의 운 나쁜 버그가 아니었다. 그것은 강력한 옵티마이저를 속아 넘어갈 수 있는 시뮬레이터에 겨냥했을 때 나오는 예측 가능한 결과였다. 당신이 백테스트에 남겨둔 모든 약점은, 탐색 아래에서 하나의 전략이 된다. 옵티마이저는 당신이 강제하기를 잊어버린 바로 그 가정들을 발견해내는 기계다.

그 단서

이 실수들을 합치면 기적을 제조하는 기계를 얻게 된다. 그것은 무엇이든 살아남을 수 있으므로 모든 것을 살아남는다. 그것은 모든 것을 걸므로 살아남을 때 거대하게 살아남는다. 그리고 탐색은 그 둘을 가능한 한 강하게 해내도록 조용히 그것을 튜닝하고 있다. 그 산출물은 어떤 전략의 성과가 아니다. 그것은 아주 큰 숫자로 그려진, 버그 그 자체의 형상이다.

이것이 “생존 우선”이 슬로건이 아닌 이유다. 파산할 수 없는 백테스트는, 탐색할 설정이 충분히 많이 주어지면, 언제나 결국 천재처럼 보이는 하나를 떠올린다 — 그 설정이 좋아서가 아니라, 탐색이 당신 시뮬레이터의 사각지대를 끈기 있게 채굴하고 있기 때문이다. 그 인상적인 숫자는 증상이다. 빠진 파산이 질병이다.

지루한 수정

수리는 멋스럽지 않았다. 포지션 크기는 계좌 전체가 아니라 계좌의 작고 고정된 비율이 되었고, 그래서 한 번의 승리가 헛소리로 눈덩이처럼 불어날 수 없었고 한 번의 손실이 전부 아니면 전무가 될 수 없었다. 시뮬레이터는 진짜 파멸 조건을 얻었다. 즉, 최소 생존 잔고 아래로 떨어지면 실행은 종료되고, 죽은 것으로 표시되며, 끝이다. 그리고 그것은 최소 주문 크기를 얻었고, 그래서 실제 시장에 존재하기에는 너무 작은 거래가 죽어가는 계좌를 조용히 생명 유지 장치에 매달아 둘 수 없었다.

이 중 어느 것도 영리한 아이디어가 아니다. 거기엔 통찰도 없고, 엣지도 없다. 그것들은 시뮬레이션이 마침내 현실이 결코 느슨하게 풀어주지 않는 제약들에 복종하기로 동의한 것일 뿐이다 — 당신을 봐주지 않는 비용, 무한하지 않은 유동성, 그리고 돌아올 수 없는 0. 정직한 백테스트를 만드는 작업의 대부분은 정확히 이것이다. 그것을 더 똑똑하게 만드는 게 아니라, 그것이 속임수를 쓰도록 내버려두기를 거부하는 것. 정직한 백테스트의 첫 번째 책임은 당신에게 수익을 보여주는 것이 아니다. 그것은 당신에게 파멸을 보여줄 수 있는 능력을 갖추는 것이다.

내가 좋은 소식을 더는 믿지 않게 된 이유

여기 불편한 부분이 있다. 버그는 쉬웠다. 어려웠던 것은 내가 거의 들여다보지 않을 뻔했다는 점이다 — 왜냐하면 그 숫자는 내게 유리했고, 나는 그게 진실이기를 원했기 때문이다. 당신과 모순되는 결과는 심문을 받는다. 당신에게 아첨하는 결과는 믿어진다.

그 비대칭이 이 일에서 대부분의 자기기만이 사는 곳이다. 사람들이 자기 버그를 못 찾는 게 아니다. 버그가 그들에게 돈을 지불하기 시작하는 순간 그들이 찾기를 멈춘다는 것이다. 시장은 결국 당신이 한 번도 확인하지 않은 모든 편안한 가정에 대해 제값을 청구할 것이다 — 하지만 백테스트는 당신이 그 가정을 몇 달이고 기꺼이 붙들고 있게 해줄 것이다. 왜냐하면 그것은, 구조적으로, 틀리는 것이 공짜인 유일한 장소이기 때문이다.

그것이 실제로 바꾼 것

그래서 가짜 조 단위의 돈에서 내가 간직한 규율은 포지션 사이징과는 거의 아무 관련이 없다. 그것은 내 신뢰의 순서를 바꿨다. 보기 좋은 결과는 이제 무죄가 입증되기 전까지 유죄다. “어떻게 이걸 해냈지?”라고 묻기 전에, 나는 “여기서 뭐가 망가졌지?”라고 묻는다 — 그리고 나는, 시장이 기회를 얻기 전에, 의도적으로 내 손으로 그것을 부수려고 시도한다. 그 적대적인 처우를 살아남는 결과들만이 내가 스스로에게 믿도록 허락하는 유일한 것이고, 그런 것들은 내가 바라는 것보다 훨씬 적다.

모든 것을 잃을 수 없는 백테스터는 낙관적인 게 아니다. 그것은 거짓말을 하고 있는 것이다. 그리고 그것이 할 수 있는 가장 위험한 거짓말은 당신이 이미 듣기를 바라고 있던 바로 그것이다.

— 시그널도, 수익도 없으며, 투자 자문이 아니다.