데이터를 정직하게 모으는 일을 다룬 DDKM Studio AI Quant 2편 대표 이미지

[제 2편] 데이터부터 정직해야 했다

User avatar placeholder
Written by DDKM

6월 18, 2026

주가 데이터를 모으며 피한 두 함정

좋은 전략을 만들기 전에, 정직한 데이터부터 갖춰야 했습니다.

지난 글에서 시스템을 만드는 과정을 여섯 단계로 나눴습니다. 그 첫 단계가 데이터 수집이었습니다. 분석의 재료인 주가 데이터를 모으는 일이죠. 가장 단순해 보이는 단계입니다. 그냥 받아오면 되는 것 아닌가 싶었습니다.

그런데 바로 이 첫 단계에서, 저는 하마터면 두 번 속을 뻔했습니다. 둘 다 데이터가 조용히 거짓말을 하는 종류였습니다. 그게 무서운 점입니다. 코드는 멀쩡히 돌아가고, 결과 숫자도 그럴듯하게 나옵니다. 다만 그 숫자가 틀렸을 뿐입니다.

분석의 재료부터 모은다는 것

제가 모아야 했던 건 수천 개 종목의 약 20년치 가격과 거래량이었습니다. 2005년 무렵부터 지금까지죠.

처음엔 다운로드 문제라고만 생각했습니다. 종목 목록을 정하고, 그 종목들의 과거 가격을 내려받으면 끝. 하지만 진짜 질문은 다운로드가 아니라 그 앞에 있었습니다. “어떤 종목을 모을 것인가.” 이 선택 하나가 뒤따르는 모든 검증의 정직함을 결정했습니다.

첫 번째 함정 — 살아남은 종목만 보고 있었다

가장 손쉬운 방법은 이렇습니다. 오늘 시장에서 거래되는 종목 목록을 받아온다. 그 종목들의 과거 데이터를 모은다. 끝.

그런데 여기에 함정이 숨어 있습니다. 오늘 거래되는 종목만 모으면, 그동안 망하거나 상장폐지돼 사라진 종목들이 데이터에서 통째로 빠집니다. 지금 살아있는 회사들만 남는 거죠.

왜 이게 문제일까요. 백테스트란 결국 “과거에 이 조건이 나타났을 때 결과가 어땠나”를 세는 일입니다. 그런데 망한 종목이 빠진 데이터로 세면, 그 망한 사례들은 처음부터 없던 일이 됩니다. 실패한 거래가 통계에서 지워지는 셈입니다. 그러면 결과는 실제보다 좋게 나옵니다. 그것도 꽤 많이.

이걸 생존편향(survivorship bias)이라고 부릅니다. 유명한 옛날 이야기가 있습니다. 2차 대전 때, 돌아온 전투기들의 총탄 자국을 분석해 그 부분을 보강하려 했답니다. 그런데 한 통계학자가 반대로 말했습니다. 보강해야 할 곳은 탄 자국이 있는 곳이 아니라, 탄 자국이 없는 곳이라고. 그곳에 맞은 비행기는 아예 돌아오지 못했으니, 데이터에 남아 있지 않았던 겁니다.

제 데이터도 똑같은 위험에 놓여 있었습니다. 돌아온 비행기만 보고 “우리 비행기는 튼튼하다”고 결론 내리는 것. 살아남은 종목만 보고 “이 조건은 승률이 높다”고 믿는 것. 둘은 정확히 같은 실수였습니다.

오늘 살아남은 종목만 모으면 상장폐지된 종목이 빠져 백테스트 승률이 부풀려지는 생존편향 도식

두 번째 함정 — 종목 목록이 늙고 있었다

첫 번째 함정은 그래도 알려진 함정이라 피하기 쉬웠습니다. 사라진 종목까지 포함해 목록을 크게 한 번 만들어두면 되니까요.

문제는 그다음이었습니다. 그렇게 만든 목록을 고정해두자, 두 번째 함정이 찾아왔습니다.

목록을 한 번 정해 박아두면, 시간이 갈수록 현실과 두 방향으로 어긋납니다.

하나, 그사이 인수합병이나 상장폐지로 사라진 종목이 목록에 유령처럼 남습니다. 예를 들어 액티비전 블리자드(ATVI), 자일링스(XLNX), 시젠(SGEN) 같은 회사들은 다른 기업에 인수되며 시장에서 사라졌습니다. 그런데 제 고정 목록에는 여전히 살아 있는 종목처럼 박혀 있었습니다.

둘, 더 중요한 문제입니다. 그사이 새로 상장한 강한 성장주가 목록에 들어오지 못합니다. 목록은 과거에 멈춰 있는데, 시장은 계속 새 얼굴을 내놓으니까요.

이게 왜 치명적이었냐면, 제 시스템의 한 축인 돌파 전략은 바로 그 새로 떠오르는 강한 성장주를 노리는 전략이기 때문입니다. 그런데 정작 그런 종목들이 목록에 없다면, 전략은 멀쩡한데 사냥할 먹잇감 자체가 비어버립니다. 사냥꾼은 준비됐는데 사냥터가 텅 빈 셈이죠. 이건 단순한 데이터 누락이 아니라, 전략의 존재 이유와 정면으로 부딪히는 구조적 결함이었습니다.

고정된 종목 목록이 상폐 종목을 남기고 새 성장주를 받지 못하는 유니버스 노후화 도식

목록을 ‘살아있게’ 만들기로 했다

답은 분명했습니다. 목록을 고정값으로 박아두지 말고, 갱신할 때마다 새로 받아오는 ‘살아있는 목록’으로 바꾸는 것.

그래서 종목 목록은 Finnhub라는 데이터 서비스에서 받아오기로 했습니다. 받아올 때마다 최신 상태라, 새로 상장한 종목이 자동으로 들어오고 사라진 종목은 빠집니다. 한 번 박아두고 늙어가는 목록이 아니라, 매번 갈아주는 목록인 셈입니다.

다만 받아온 목록을 그대로 다 쓰지는 않았습니다. 그 안에는 ETF, 우선주, 거래가 거의 없는 초저가 종목 같은 노이즈가 섞여 있습니다. 분석 대상으로 삼기 어려운 것들이죠. 그래서 정규 보통주만 남기는 거름망을 한 번 거쳤습니다.

그래서 무엇을 모았나 — 네 가지 재료

종목 목록을 정리하고 나면, 이제 그 종목들에 대해 실제로 무엇을 모을지가 남습니다. 제 시스템이 분석하는 원재료는 크게 네 가지입니다.

  • 종목 목록 — 지금 어떤 종목이 상장돼 있는가. 앞서 말한 Finnhub에서 받아오는, 매번 갱신되는 ‘살아있는 목록’입니다.
  • 가격과 거래량 — 각 종목의 약 20년치 일별 시세입니다. yfinance에서 모읍니다. 분석의 가장 기본이 되는 뼈대죠.
  • 분기 실적(EPS 등) — 차트만 좋은 종목이 아니라 실적까지 받쳐주는 종목을 가리려면, 회사가 실제로 얼마를 버는지가 필요합니다. 이 실적 데이터는 Sharadar SF1에서 가져옵니다. 믿을 만한 분기 실적은 공짜로 구하기 어려워, 네 재료 중 이것만큼은 비용을 들여 유료로 받습니다.
  • 지수 데이터 — 개별 종목만 봐서는 시장 전체가 좋은지 나쁜지를 알 수 없습니다. 그래서 시장을 대표하는 지수도 함께 모읍니다. S&P500(SPY), 나스닥100(QQQ), 그리고 공포지수라 불리는 VIX 같은 것들입니다. 이 데이터가 있어야 “지금 시장이 사도 되는 분위기인가”를 판단할 수 있습니다.

이 네 가지가 제 시스템의 입력입니다. 종목이 누구인지, 그 종목이 어떻게 움직였는지, 실제로 돈을 버는지, 그리고 시장 전체는 어떤 상태인지. 여기까지가 ‘날것의 재료’를 모으는 단계입니다.

DDKM AI 시스템이 종목 목록·가격·실적·지수 네 가지 데이터를 수집하는 구조 도식

한 번에 다 받지 않는다 — 너무 무거우니까

여기서 현실적인 문제가 하나 생겼습니다. 수천 종목의 20년치를 통째로 다시 받는 작업은 한 번 돌리는 데 한참 걸립니다. 이걸 매일 할 수는 없었습니다.

그래서 수집을 둘로 쪼갰습니다.

평소에는 이미 가진 목록의 최근 며칠 치만 덧붙여 갱신합니다. 가볍고 빠릅니다. 대신 이 방식은 새로 상장한 종목은 못 찾습니다. 자기가 아는 목록만 보니까요.

그래서 한 달에 한 번꼴로, 목록 자체를 새로 받아 전체를 다시 정비합니다. 새로 상장한 성장주는 바로 이때 시스템 안으로 들어옵니다. 평소엔 가볍게, 가끔은 무겁게. 이 두 박자로 매일의 속도와 목록의 신선함을 동시에 챙겼습니다.

데이터를 바꿨으면, 결과부터 다시 의심한다

여기서 끝낼 수도 있었습니다. 하지만 한 가지가 마음에 걸렸습니다. 데이터를 통째로 갈아끼웠다는 건, 그 위에서 검증했던 기존 결과가 흔들릴 수도 있다는 뜻이었으니까요.

저는 숫자로 증명되기 전엔 믿지 않는 편입니다. 그래서 그냥 넘어가지 않고 따로 확인했습니다. “데이터를 새것으로 바꿨더니, 기존 시스템의 판단이 달라지는가?” 이 질문에 숫자로 답을 내기 전까지는, 새 데이터를 운영에 올리지 않았습니다.

데이터를 바꾸는 일은 집의 바닥을 들어내는 일과 같습니다. 바닥을 새로 깔았으면, 그 위에 서 있던 가구들이 여전히 제자리에 있는지부터 확인해야 합니다. 그 확인 과정 이야기는 다음 글들에서 더 자세히 다루겠습니다.

솔직히 — 공짜는 아니었다

지난 글에서, AI 덕분에 코딩을 못하는 개인도 자기만의 검증 시스템을 가질 수 있게 됐다고 했습니다. 맞는 말입니다. 다만 한 가지는 솔직히 덧붙여야겠습니다. 완전히 공짜는 아니었습니다.

종목 목록과 가격 데이터는 무료 도구로 해결할 수 있었습니다. 하지만 믿을 만한 분기 실적만큼은 매달 비용을 내고 받고 있습니다. 데이터의 품질이 곧 검증의 정직함을 좌우하기 때문입니다. 생각해보면 이번 글의 두 함정 — 생존편향도, 유니버스 노후화도 — 결국 “이 데이터를 믿을 수 있는가”라는 같은 질문이었습니다. 그 믿음을 사는 일이라면, 이 부분은 아끼지 않는 게 맞다고 판단했습니다.

이번 편이 남긴 것

데이터 수집은 여섯 단계 중 가장 단순해 보이는 첫 단계였습니다. 하지만 여기서 데이터가 거짓말을 하거나(생존편향), 늙어버리면(유니버스 노후화), 그 위에 아무리 정교한 모델을 쌓아도 전부 모래성이 됩니다. 화려한 전략보다, 무엇을 데이터에 넣고 무엇을 뺄 것인가가 먼저였던 셈입니다.

5년간 검색식만 만들던 사람이 가장 먼저 부딪힌 벽도 결국 데이터였습니다. 그리고 이 벽을 정직하게 넘는 것이, 뒤따르는 모든 검증을 믿을 수 있게 만드는 토대였습니다.

다음 편에서 다룰 것

데이터를 모았으니, 다음은 그 데이터에 의미를 입힐 차례입니다. 원시 가격을 그대로는 못 씁니다. 이동평균선, 거래량 비율, 신고가 대비 위치 같은 지표로 바꿔야 비로소 분석이 시작됩니다.

그리고 더 까다로운 질문이 기다리고 있습니다. “성공한 매수란 무엇인가.” 승률을 따지려면, 먼저 ‘승’이 무엇인지부터 숫자로 못 박아야 합니다. 며칠 안에 몇 퍼센트가 오르면 성공이고, 얼마나 빠지면 실패인가. 이 정의 하나가 흔들리면 ‘승률’이라는 말 자체가 성립하지 않습니다. 다음 글에서 그 이야기를 이어가겠습니다.


미리 분명히 해둘 게 있습니다. 이 시리즈는 특정 종목을 추천하는 글이 아닙니다. 글에 등장하는 검증 결과 역시 과거 데이터를 분석한 수치일 뿐, 미래의 수익을 보장하지 않습니다. 모든 투자의 책임은 투자자 본인에게 있습니다. 이 시리즈가 전하려는 것은 종목이 아니라, 한 개인이 데이터에 속지 않으려 애쓴 과정입니다.

📩 문의사항 :  intothepado@gmail.com