같은 이름의 다른 물건 — 수정주가라는 함정

2026-07-15

FomoBot의 KOSPI 데이터는 pykrx에서, NASDAQ 데이터는 yfinance에서 옵니다. 둘 다 "수정주가"를 제공합니다. 액면분할이나 증자로 주가가 계단처럼 튀는 걸 소급 조정해, 수익률 계산이 어긋나지 않게 해주는 값입니다.

이름이 같으니 같은 물건이라고 생각했습니다. 그게 틀렸습니다.

pykrx의 수정주가는 배당을 빼고, yfinance의 수정주가는 배당을 넣습니다. 이름은 같고 값이 다릅니다.

그리고 이 사실을 몰랐던 탓에, 한동안 이 사이트의 방법론 문서가 스스로의 계산 방식을 잘못 설명하고 있었습니다. 이 글은 그 버그의 기록이자 정정입니다.

어떻게 발견했나

다른 글(5년 수익률 1위)을 준비하면서 KOSPI 1위 종목의 수익률을 교차검증하던 중이었습니다. 우리 DB의 pykrx 데이터와, 완전히 독립된 소스인 yfinance를 나란히 놓고 같은 종목을 조회했습니다.

같은 종목, 같은 5년 구간 — 두 소스의 수익률
종료일 종가5년 수익률
pykrx (우리 DB)788,000원+3,582%
yfinance (독립 검증)788,000원+3,767%

종료일 종가는 원 단위까지 정확히 일치했습니다. 그런데 5년 수익률은 약 185%p 벌어졌습니다.

처음에는 조정 오류를 의심했습니다. 어느 한쪽이 액면분할을 빠뜨렸다면 이런 차이가 날 수 있으니까요. 하지만 종료가가 정확히 같고, 5년 구간 어디에도 하루 만에 30%를 넘는 급등락(분할 누락의 흔적)이 없었습니다. 조정은 양쪽 다 제대로 돼 있었습니다.

남는 설명은 하나였습니다. 배당.

왜 차이가 나는가

pykrx가 따르는 KRX의 "수정주가" 정의는 액면분할·병합, 무상증자·유상증자로 인한 가격 변동만 소급 반영합니다. 현금배당은 반영하지 않습니다. 그래서 pykrx 기반 수익률은 순수한 주가 등락만 담습니다.

yfinance는 다릅니다. 배당까지 역산해 주가에 녹여 넣습니다. 배당락으로 주가가 떨어진 만큼을 과거 가격에서 차감하는 방식이라, 배당을 재투자했다고 가정한 총수익에 가깝습니다.

그러니 배당을 꾸준히 준 종목이라면, 5년치 배당수익률만큼 yfinance 쪽 수익률이 더 높게 나옵니다. 185%p의 정체가 그것이었습니다. 배당을 재투자한 세계와 안 한 세계의 차이입니다.

확인을 위해 배당 이력이 뚜렷한 종목을 하나 잡아 yfinance의 조정 옵션을 켜고 끄며 비교했습니다. 옵션을 켜면 배당이 반영돼 수익률이 올라갔습니다. 정의를 문서로 읽는 것과, 데이터에서 실제로 그 차이를 보는 것은 다른 일입니다. 후자를 하고 나서야 확신할 수 있었습니다.

그래서 무엇이 틀려 있었나

문제는 우리 방법론 문서였습니다. 그 문서는 수정주가를 이렇게 설명하고 있었습니다 — "액면분할·배당 등을 반영해 조정한 종가."

KOSPI와 NASDAQ을 구분하지 않고 한 문장으로 뭉뚱그린 설명이었습니다. 그리고 이 문장은 절반만 맞았습니다.

실제 계산 방식 vs 문서의 설명
시장 (소스)배당 반영문서 설명
NASDAQ (yfinance)반영됨맞음
KOSPI (pykrx)반영 안 됨틀림

NASDAQ에 대해서는 맞는 설명이었지만, KOSPI에 대해서는 하지도 않는 일을 한다고 적어둔 셈이었습니다. 데이터가 틀린 게 아니라 데이터를 설명하는 문서가 틀렸습니다. 어떤 면에서는 이게 더 나쁩니다. 숫자는 맞는데, 그 숫자가 무엇을 뜻하는지에 대한 설명이 틀렸으니까요.

왜 이런 실수가 쉬운가

이건 오타가 아닙니다. 이름이 같으면 값도 같을 거라고 가정한 데서 온 실수입니다.

두 라이브러리가 모두 "adjusted close"라는 같은 이름의 컬럼을 내놓습니다. 타입도 같고, 형태도 같고, 그럴듯한 숫자가 들어 있습니다. 코드는 아무 불평 없이 돌아갑니다. 오류 메시지도, 예외도 없습니다. 두 값이 서로 다른 정의를 따른다는 사실은 숫자만 봐서는 절대 드러나지 않습니다.

같은 이름의 컬럼이 두 소스에서 다른 것을 뜻할 때, 코드는 그 차이를 알려주지 않습니다. 두 값을 나란히 놓고 "왜 다르지?"라고 물어보는 사람만 알 수 있습니다.

그리고 이 함정은 소스를 하나만 쓰면 영영 드러나지 않습니다. KOSPI만 다뤘다면 pykrx의 정의가 곧 우리의 정의였을 테니 아무 문제가 없었을 겁니다. 두 시장을 한 서비스에 담고, 한쪽을 다른 쪽으로 교차검증하는 과정에서야 비로소 불일치가 드러났습니다.

어떻게 고쳤나

방법론 문서를 고쳤습니다. "배당 등을 반영"이라는 뭉뚱그린 표현을 지우고, pykrx 수집분은 "액면분할·무상증자·유상증자를 반영, 현금배당은 미반영"으로 정확히 다시 적었습니다. 헷갈리기 쉬운 용어인 만큼 용어 해설로 가는 링크도 함께 걸어, 읽는 사람이 정의를 바로 확인할 수 있게 했습니다.

그리고 한 문장을 더 넣었습니다 — 두 시장의 수익률을 직접 비교할 때는 이 비대칭을 감안해야 한다. KOSPI 종목과 NASDAQ 종목을 나란히 세우면, 배당을 주는 종목일수록 NASDAQ 쪽이 구조적으로 유리하게 보입니다. 같은 시장 안에서의 순위 비교는 영향받지 않지만, 시장을 가로지르는 비교에는 이 각주가 반드시 따라붙어야 합니다.

이 사이트의 개별 랭킹은 KOSPI와 NASDAQ이 분리돼 있어 순위 자체는 안전합니다. 하지만 지수 간 비교처럼 두 시장을 한 화면에 놓는 글에서는, 이 차이를 각주로 밝히는 것이 최소한의 정직입니다.

왜 이걸 글로 쓰는가

조용히 고치고 넘어갈 수도 있었습니다. 문서 한 줄을 바꾸는 일이니까요.

그러지 않는 이유는, 이 사이트가 파는 것이 결국 숫자에 대한 신뢰이기 때문입니다. 우리는 매일 수익률과 최대낙폭을 보여주고, 그게 정확하다고 주장합니다. 그렇다면 그 숫자가 무엇을 뜻하는지에 대한 설명이 틀렸던 적이 있다는 사실도 같이 공개하는 게 맞습니다.

틀린 적 없다고 말하는 서비스보다, 어디서 어떻게 틀렸고 어떻게 고쳤는지 말하는 서비스를 믿는 편이 합리적입니다. 적어도 후자는 검증을 하고 있다는 뜻이니까요.

"수정주가"는 앞으로도 두 소스에서 다른 것을 뜻할 겁니다. 우리는 이제 그걸 알고, 문서에 그렇게 적어 두었습니다.

데이터 기준 — 교차검증은 2026-07 기준으로 수행했으며, 사용한 5년 구간과 종목의 세부 수치는 해당 글에 있습니다. pykrx와 yfinance의 수정주가 정의는 각 라이브러리 및 KRX의 공개 정의에 따른 것으로, 향후 각 소스의 정책이 바뀌면 달라질 수 있습니다.

배당 처리 — 이 글에서 설명한 대로, KOSPI(pykrx) 수익률은 배당 미반영, NASDAQ(yfinance) 수익률은 배당 반영입니다. 최신 정의는 방법론을 참고하십시오.

투자 판단에 대하여 — FomoBot은 이미 지나간 가격을 정리해 보여주는 도구입니다. 특정 종목의 매수·매도를 권유하지 않으며, 이 글의 어떤 내용도 투자 자문이 아닙니다. 투자 손익의 책임은 투자자 본인에게 있습니다.