고칠 수 있었지만 고치지 않은 것
FomoBot의 백테스트에는 알려진 결함이 하나 있습니다. 상장폐지된 종목이 계산에서 빠집니다. 그래서 모든 수익률이 실제보다 관대하게 나옵니다.
이건 고칠 수 있는 결함입니다. 그리고 우리는 고치지 않기로 결정했습니다. 이 글은 그 결정의 기록입니다.
생존 편향이 무엇인지 자체는 별도 페이지에 정리해 뒀습니다. 여기서는 그 개념이 아니라, "고칠 수 있는데 왜 안 고쳤는가"만 다룹니다.
왜 종목이 사라지는가
백테스트는 "과거의 어느 날 이 종목을 샀다면 지금 얼마"를 계산합니다. 그러려면 그 종목의 현재 가격이 필요합니다.
상장폐지된 종목에는 현재 가격이 없습니다. 거래가 끝났으니까요. 현재 가격이 없으면 수익률을 계산할 수 없고, 계산할 수 없으면 그 종목은 결과에서 조용히 빠집니다.
그래서 백테스트에 남는 것은 오늘까지 살아남은 종목들뿐입니다. 망한 회사, 상장폐지된 회사, 거래정지된 회사는 애초에 계산에 참여하지 못합니다. 살아남은 자들만 성적표에 이름을 올립니다.
이것이 결과를 낙관적으로 만듭니다. 특히 급락주를 다룬 분석에서 이 편향은 치명적이었습니다. 많이 떨어진 종목일수록 그다음에 상장폐지될 확률이 높은데, 그 최악의 사례들이 데이터에서 사라진 채로 "역발상 매수의 성적"이 계산됩니다. 실제 성적은 언제나 표에 적힌 것보다 나빴습니다.
고치는 방법은 있습니다
해결책 자체는 명백합니다. 상장폐지된 종목의 폐지 시점 가격이나 마지막 거래가를 확보해, 현재 가격이 없을 때 그 값으로 대신 계산하면 됩니다. 폐지가 사실상 -100%에 가까운 경우라면 그렇게 반영하면 됩니다.
그러면 사라졌던 종목들이 계산에 돌아오고, 수익률은 지금보다 낮게 — 더 현실에 가깝게 — 나옵니다.
우리는 이 방향의 코드를 의식적으로 넣지 않았습니다. 백테스트를 다시 설계할 때, "현재 가격이 없는 종목을 다른 값으로 대체하는 처리"를 명시적으로 금지했습니다. 값이 없으면 없는 채로 두고, 그 종목은 빠지게 놔둡니다. 편향을 지우는 코드를 일부러 거부한 셈입니다.
왜 그랬는가. 이유가 세 겹입니다.
이유 1 — 완벽하게 복원해도 여전히 불완전하다
가장 중요한 이유입니다.
상장폐지 종목을 전부 복원했다고 칩시다. 그래도 데이터는 여전히 불완전합니다. 어떤 종목의 폐지 시점 가격이 정확히 얼마였는지, 거래정지 구간을 어떻게 처리할지, 정리매매 가격을 쓸지 마지막 정상 거래가를 쓸지 — 판단이 필요한 지점이 끝없이 나옵니다. 그 판단마다 새로운 편향이 스며듭니다.
완벽한 복원은 불가능합니다. 그런데 어설프게 복원하고 나면, "이제 생존 편향을 고쳤다"는 거짓 확신이 생깁니다. 이게 안 고친 것보다 위험합니다.
지금은 모두가 압니다 — 이 수치는 관대하다고. 사용자도 알고 우리도 압니다. 그런데 "생존 편향 보정 완료"라는 라벨을 붙이는 순간, 그 라벨을 믿게 됩니다. 여전히 불완전한 수치에 "정확함"의 도장이 찍힙니다. 알려진 결함은 경계되지만, 고쳤다고 선언된 결함은 방심을 부릅니다.
이유 2 — 경고가 보정보다 정직하다
그래서 우리는 반대 방향을 택했습니다. 편향을 없애는 대신, 편향이 있다는 사실을 항상 함께 내보냅니다.
백테스트 결과에는 "이 수치는 상장폐지 종목이 빠져 실제보다 관대하다"는 경고가 늘 따라붙습니다. 이건 사용자가 눈여겨보든 말든 매번 실려 나갑니다. 결과를 조용히 보정하는 대신, 결과의 한계를 시끄럽게 명시하는 쪽입니다.
둘의 차이는 이렇습니다. 보정은 "우리가 알아서 처리했으니 믿으라"고 말합니다. 경고는 "여기 이런 한계가 있으니 감안해서 읽으라"고 말합니다. 전자는 신뢰를 요구하고, 후자는 판단을 넘겨줍니다. 지나간 가격을 보여주는 게 전부인 이 서비스에서는, 판단을 넘겨주는 쪽이 맞습니다.
이유 3 — 이건 코드로 지켜지는 결정이다
이 결정이 말뿐이 아니라는 점이 중요합니다.
"정직하게 하겠다"는 다짐은 쉽습니다. 하지만 시간이 지나면 흐려지고, 어느 순간 누군가 "현재 가격 없으면 마지막 값으로 채우자"는 편리한 코드를 슬쩍 넣습니다. 좋은 의도로요. 그러면 편향은 소리 없이 다시 지워지고, 경고 문구만 유령처럼 남습니다.
그래서 이건 방침 문서가 아니라 구현된 규칙으로 박혀 있습니다. 현재 가격이 없을 때 다른 값으로 대체하지 않는 것, 그리고 결과에 한계 경고를 항상 포함하는 것 — 둘 다 코드가 그렇게 동작하도록 만들어져 있습니다. 나중에 누군가 편향을 지우려면, 이 결정을 코드에서 의도적으로 되돌려야 합니다. 실수로는 안 됩니다.
정리 — 정직의 두 가지 방식
데이터의 결함을 정직하게 다루는 방법은 두 가지입니다. 고쳐서 없애거나, 남겨두고 알리거나.
대부분의 경우 고치는 게 낫습니다. 하지만 완벽하게 고칠 수 없는 결함이라면, 어설프게 고치고 "해결됐다"고 말하는 것보다 남겨두고 "여기 있다"고 계속 말하는 편이 정직합니다. 생존 편향이 그런 결함입니다.
그래서 FomoBot의 수익률은 앞으로도 실제보다 관대할 겁니다. 그리고 그 옆에는 앞으로도 "이 수치는 관대하다"는 경고가 붙어 있을 겁니다. 이 두 문장이 나란히 있는 상태가, 우리가 고를 수 있는 가장 정직한 형태입니다.
이 글에 관하여 — 여기 적은 것은 FomoBot 백테스트의 설계 결정입니다. 상장폐지·거래정지 종목은 현재 가격이 없어 백테스트 계산에서 제외되며, 이를 다른 값으로 대체하지 않습니다. 백테스트 결과에는 생존 편향으로 인해 수치가 실제보다 낙관적일 수 있다는 안내가 함께 제공됩니다.
투자 판단에 대하여 — FomoBot은 이미 지나간 가격을 정리해 보여주는 도구입니다. 백테스트 수치는 생존 편향으로 인해 실제보다 관대하며, 특히 하락 종목 분석에서 그 정도가 큽니다. 이 글의 어떤 내용도 투자 자문이 아닙니다.