나스닥 차트에서 닮은 과거 패턴 찾기
나스닥 지수 데이터로 지금과 닮은 과거 구간을 찾아주는 프로젝트를 만들었다
6/24/2026 · 6 min read
지금 차트 모양이 예전에도 있었다면 그 다음엔 어떻게 됐을까. 미래를 예측할 수 있을까? 이 질문 하나로 시작한 프로젝트다.
2024년, 수업 과제로
DB 수업 팀 프로젝트였고 나는 프론트엔드를 주도적으로 진행했다. 캔들스틱 차트를 그리고 기간을 고르면 백엔드에서 받아온 유사 구간을 옆에 띄우는 화면이었다.
이 과정에서 배포 후 치명적인 문제가 발생했는데, 이후에 서술하겠다.
유사도 계산이나 API는 나머지 3명의 팀원이 짰다. 나스닥 일봉 데이터 1980~2024년치, 약 11000개를 ApexCharts로 그려서 학기 안에 발표까지 마쳤다.
그러고는 그대로 숙성시켰다.
2026년, 다시 열어본 날
오랜만에 다시 열어봤는데 캔들이 그려지다 멈췄다. 한참 기다려야 화면이 나왔다. 앞서 말한 그 치명적인 문제였다. 수업 때는 데이터를 일부만 넣고 돌렸으니 그때는 드러나지 않았던 거였다.
원래 만들고 싶었던 건 기간 하나 고르면 바로 닮은 과거가 튀어나오는 화면이었다.
지금처럼 개느리면 그 경험 자체가 안 되는 거였다. 그래서 백엔드 탓이라고 단정하지 않고 하나씩 측정해보기로 했다. 내가 찾은 병목은 세 군데였다.
응답 크기. API 응답이 너무 컸다. 필드를 줄이거나 기간을 잘라 보낼 수도 있었지만, 전체 기간을 다 보여줘야 하는 게 이 프로젝트의 핵심이라 데이터 자체를 줄이고 싶지는 않았다.
그래서 데이터는 그대로 두고 FastAPI에 gzip 미들웨어 한 줄만 추가했다(이걸 왜 이제 한거임?;;)
응답 시간. 데이터가 한 번 만들어지면 바뀌지 않는다는 점에 주목했다.
기간·지표 조합마다 정적 파일을 미리 만들어두는 방법도 있었지만 조합이 늘어날 때마다 파일을 새로 만들어야 해서 유연성이 떨어졌다.
함수 안에서 메모리에 캐시하는 방법도 있었지만, 서버리스 함수가 매 요청마다 콜드 스타트하는 문제는 그걸로 해결되지 않았다.
그래서 첫 요청 이후로는 백엔드를 거치지 않는 엣지 캐싱을 선택했다.
유사도 계산도 매번 새로 하지 않도록 DP느낌을 이용해 database.py로 CSV를 SQLite에 적재하고 cosine.py로 미리 계산해서 저장해뒀다.
python database.py # CSV를 DB에 적재
python cosine.py # 유사도 미리 계산응답이 눈에 띄게 빨라졌다. 그제서야 차트가 버벅이지 않고 한눈에 들어왔다.
차트 렌더링. ApexCharts는 캔들 하나마다 SVG 엘리먼트를 그리는 구조라 1만 개가 넘어가면 구조적으로 느렸다. 데이터를 줄이는 건 역시 핵심 기능을 포기하는 거라 선택지가 아니었다. 그래서 캔버스 기반인 lightweight-charts로 바꿨다. 캔들 11125개도 끊김 없이 그려졌고, ApexCharts를 빼면서 JS 번들도 같이 줄었다.
크기와 응답 시간은 curl로, 번들 크기는 빌드 결과로 직접 재서 확인했다.
| 항목 | 이전 | 이후 |
|---|---|---|
| API 응답 크기 | 1.99MB | 263KB |
| 응답 시간 | 약 2초 | 0.15~0.49초 |
| JS 번들(gzip) | 183KB | 99KB |
이 측정과 최적화는 전부 팀 프로젝트를 넘겨받은 뒤 혼자 진행했다.
돌아보며
처음 맡았던 건 화면 하나였다. 2년 뒤에 다시 열어보니 그 화면을 떠받치던 데이터 양과 구조가 그대로 문제로 드러났다.
기능을 만들 때는 보이지 않던 게 데이터가 쌓이고 나서야 보였다.
"느리다"는 느낌을 그냥 두지 않고 측정 가능한 수치로 쪼개본 게 이번에 제일 남는 부분이다.
압축이냐 데이터 절단이냐, 정적 캐시냐 엣지 캐싱이냐처럼 선택지가 여러 개일 때마다 각각의 트레이드오프를 따져보고 골랐다.
원인을 하나씩 찾아 고치고 숫자가 줄어드는 걸 눈으로 확인하는 과정이 제일 재밌었다.
실행 방법
cd back
pip install -r requirements.txt
uvicorn main:app --reload
cd front
npm install
npm startAPI 세 개는 팀원이 2024년에 만든 걸 그대로 쓰고 있다.
(개선 해야하는데 언제하지?)
GET /nasdaq_chart— 일봉 OHLC 데이터GET /similar_patterns— 기간과 지표를 받아 실시간으로 유사 구간 계산GET /cosine_similarity— 미리 계산해둔 유사 구간 목록