“한국 주식이니까 벤치마크는 코스피200.” 포트폴리오 성과를 잴 때 자연스럽게 나오는 선택인데, 이게 틀릴 수 있습니다. 같은 포트폴리오, 같은 기간, 같은 거래 내역의 알파(내 수익률에서 벤치마크 수익률을 뺀 초과수익)가 벤치마크를 코스피200에서 보유 비중 혼합 지수로 바꾸자 −31.87%p에서 +7.62%p로 뒤집혔습니다. %p는 퍼센트포인트, 수익률끼리의 차이입니다.
이 글의 답은 이렇습니다.
벤치마크는 시장의 이름이 아닌, 내가 취한 노출이어야 합니다.
코스닥 비중이 1%에서 80% 사이를 오간 포트폴리오를 코스피200 하나로 재면, 두 시장이 64%p 벌어진 넉 달 동안 알파의 부호까지 바뀝니다.
아래는 알파 식의 어느 항이 문제인지, 무슨 일이 벌어졌는지, 혼합 벤치마크를 만드는 법, 그리고 새 자로도 안심할 수 없는 이유입니다.
초과수익 식의 어느 항이 문제인가?
알파 = 내 수익률 − 벤치마크 수익률
왼쪽 항에는 논쟁의 여지가 없습니다.
거래가 있었고, 가격이 있었고, 결과가 있습니다.
논쟁은 오른쪽 항에서 벌어집니다.
오른쪽 항은 “시장”이라는 실체처럼 보이지만 내가 고른 어떤 지수일 뿐입니다.
이 글은 그 선택 하나가 결론을 어디까지 움직이는지에 대한 것입니다.
실제로 무슨 일이 벌어졌나?
이 포트폴리오는 모멘텀(최근에 많이 오른 종목을 고르는 방식)과 역변동성(덜 출렁이는 종목에 더 많이 배분하는 방식)으로 30종목을 골라 주 1회 리밸런싱(정해진 주기마다 종목을 다시 고르는 것)합니다. 종목 선정 규칙에는 시장 구분이 없어서 조건에 맞으면 코스피든 코스닥이든 담습니다. 그 결과 리밸런싱 시점마다 잰 코스닥 비중(장부가 기준)이 최저 1.22%에서 최고 80.09%까지 22개 스냅샷 동안 왕복했습니다(스냅샷별 수치는 부록에). 이건 규칙이 낳은 결과입니다. 코스닥이 모멘텀 상위를 차지하면 코스닥으로 채워집니다.
그런데 성과 API의 벤치마크는 const BENCHMARK_TICKER = '069500' 한 줄로 코스피200 ETF에 고정돼 있었습니다.
코스닥 비중이 80%일 때도 코스피200 지수를 자로 썼습니다.
이게 사소한 문제라면 넘어갈 수도 있습니다. 그런데 그 기간에 두 시장이 서로 반대로 갔습니다.
2026-03-27 → 07-13
코스피200 ETF +33.97 %
코스닥150 ETF −30.41 %
────────────────────────
발산폭 64.38 %p
한쪽이 3분의 1 오르는 동안 다른 쪽이 3분의 1 가까이 빠졌습니다. 이 상황에서 벤치마크를 잘못 고르면 결과가 조금 흔들리는 데서 그치지 않고 아예 다른 이야기가 됩니다.
혼합 벤치마크는 어떻게 만드나?
교정은 개념적으로 단순합니다. 내가 취한 노출과 같은 구성의 자를 만듭니다.
일간 벤치마크 수익률
r(t) = (1 − w) · r_코스피200(t) + w · r_코스닥150(t)
w = 직전 리밸런싱 시점 보유 종목의 코스닥 장부가 비중
중요한 점이 둘 있습니다.
① w 는 고정값이 아니고 리밸런싱마다 갱신됩니다
포트폴리오가 코스닥 80%에서 1%로 옮겨가면 벤치마크도 따라 옮겨갑니다. 이건 표준적인 방법이고, 혼합 벤치마크는 원래 포트폴리오와 같은 주기로 리밸런싱합니다.
② w 는 항상 과거만 봅니다
as_of_date < t 조건으로 t일의 벤치마크 가중치는 t일 이전 마지막 리밸런싱에서 가져옵니다.
오늘의 성과를 오늘의 비중으로 가중하면 미래 정보가 새어 들어갑니다. 이 조건 하나가 자를 정직하게 유지합니다.
벤치마크 수익률 알파
코스피200 단독 +33.97 % −31.87 %p
보유비중 혼합 −5.52 % +7.62 %p
벤치마크가 39.5%p 움직였고, 알파가 부호를 넘어갔습니다. 혼합 벤치마크의 −5.52%는 위에 적은 정의를 그대로 SQL로 옮겨 원본 가격에서 다시 계산한 값이고, 그 쿼리는 발행 전 자동 대조 항목에 들어 있습니다. 공개본에는 쿼리가 실리지 않습니다. 대조 상대는 내부 DB이고, 독자가 확인할 수 있는 것은 위의 정의와 두 지수의 공개 가격입니다.
그럼 새 자는 믿어도 되나?
여기서 멈추면 이 글은 자기 자랑이 됩니다.
같은 포트폴리오의 더 긴 기간(2026-03-27 → 08-21)은 수익률 −10.09%, 손실입니다.
교정이 한 일은 틀린 숫자를 맞는 숫자로 바꾼 것뿐입니다. 지고 있던 것을 이기게 만들지는 않았습니다. −31.87%p는 “이 전략이 형편없다”가 아닌 “이 측정이 틀렸다”는 뜻이었고, +7.62%p는 “이 전략이 좋다”가 아니라 “제대로 재보니 이 기간엔 그랬다”는 뜻입니다. 이 구분이 중요한 이유가 있습니다.
교정 전 숫자를 그대로 믿었다면 다음 행동은 전략을 뜯어고치는 것이었습니다.
저는 한동안 이 −31.9%p를 “레짐 판단 로직이 잘못됐다”는 증거로 읽고 있었습니다. 그런데 분해해보니 레짐 로직의 기여는 기간당 ±2~3%p짜리 소품이었고 나머지 대부분은 자가 안 맞아서 생긴 숫자였습니다.
없는 병을 고치러 갈 뻔했습니다.
교정된 벤치마크로도 여전히 조심해야 합니다. 창을 조금만 옮기면 결론이 뒤집힙니다. 같은 시작일에서 끝나는 날만 4거래일 늘려봤습니다.
07-23 → 07-31 상대성과 −9.03 %p ← 크게 밀렸다
07-23 → 08-06 상대성과 +1.79 %p ← 앞섰다
시작이 같고, 거래도 같고, 자도 같습니다.
4거래일이 더 붙었을 뿐인데 10.8%p가 움직이며 부호가 바뀌었습니다.
원인은 구조에 있습니다. 이 포트폴리오는 30종목을 비슷한 크기로 나눠 담고, 벤치마크는 시가총액 가중 지수(시가총액이 큰 종목이 지수를 더 많이 움직이는 방식)입니다. 대형주 몇 개가 튀는 날에는 지수가 이기고, 그 몇 개가 빠지는 날에는 포트폴리오가 이깁니다. 그래서 며칠짜리 상대 수치는 전략보다 시장의 그날 성격을 잽니다. 여기서 제가 정한 규칙이 하나 있습니다. 며칠짜리 상대 수치로 구조를 판정하지 않고, 창의 끝점이 큰 사건 직후인지 먼저 확인합니다. 위 두 줄은 같은 데이터에서 정반대 제목을 뽑을 수 있다는 걸 보여주는 표본입니다.
자주 묻는 질문
벤치마크를 여러 개 놓고 다 보면 안 되나요
봐도 됩니다. 다만 결과를 본 뒤에 마음에 드는 자를 고르면 그건 측정이 아닙니다. 여러 개를 볼 거라면 어느 것을 판정에 쓸지 미리 정해 두어야 합니다.
w 를 오늘 비중으로 쓰면 왜 안 되나요
오늘의 성과를 오늘의 비중으로 가중하면 미래 정보가 새어 들어갑니다. 그래서 as_of_date < t 로 직전 리밸런싱 값만 씁니다.
코스피200 ETF 수익률이 틀렸다는 뜻인가요
아닙니다. +33.97% 는 완벽하게 옳은 숫자예요. 코스닥을 80% 들고 있는 포트폴리오의 기준선이 아니었을 뿐입니다.
며칠짜리 상대 수치는 아예 보면 안 되나요
보되 구조 판정에 쓰지 않습니다. 이 글의 07-23 두 줄이 같은 데이터에서 정반대 제목을 뽑을 수 있다는 표본입니다. 창의 끝점이 큰 사건 직후인지 먼저 확인합니다.
남는 것
벤치마크는 시장의 이름이 아니라 내가 취한 노출입니다. “한국 주식이니까 코스피”는 자연스럽게 들리지만 논증은 되지 못합니다. 질문은 “이 나라 대표 지수가 뭐냐”보다 “내가 하지 않았다면 대신 무엇을 들고 있었을까”이고, 그 답이 코스피 70% + 코스닥 30%이면 자도 그래야 합니다.
벤치마크는 결과를 보기 전에 정해야 합니다. 이번 교정은 사후에 이뤄졌고, 결과적으로 제 숫자가 좋아졌습니다. 방향이 반대였다면 저는 이 교정을 똑같이 밀어붙였을까요? 그렇다고 믿지만 증명할 수 없습니다. 그래서 이런 정의는 성과를 보기 전에 문서로 고정해두는 게 맞고, 저는 그걸 다른 검증에서는 하고 있습니다. 여기서는 못 했습니다.
자를 바꿀 수 있는 사람은 답도 바꿀 수 있습니다. 그래서 자를 언제, 왜 바꿨는지가 결과 자체보다 중요합니다.
부록 1: 리밸런싱 시점별 코스닥 비중
03-27 80.09 % ████████████████
04-17 68.54 % █████████████
05-08 34.80 % ███████
06-05 35.86 % ███████
07-10 27.34 % █████
07-31 1.22 % ▏
08-21 27.42 % █████
부록 2: 교정을 검증한 방법
측정을 바꿀 때 가장 무서운 건 “고쳤다고 생각했는데 다른 걸 망가뜨린” 경우라서 셋을 확인했습니다.
하위 호환. w = 0을 넣으면 새 공식은 옛 공식과 수학적으로 같아야 합니다. 일간 수익률을 복리로 이어붙이면 중간 항이 전부 상쇄돼(telescoping) 시작과 끝 가격의 단순 비율만 남기 때문입니다. 실측으로 069500 단독 수익률이 소수점까지 재현되는 걸 확인했습니다. 이 변경은 교정이라기보다 일반화이고, 옛 계산을 특수한 경우로 포함합니다.
독립 재계산. 서비스 코드가 내놓은 −5.52%를, 코드를 보지 않고 정의만 보고 짠 SQL로 다시 계산해 일치를 확인했습니다. 같은 코드를 두 번 실행하는 것으로는 검증이 되지 않습니다.
저장하지 않기. 이 변경은 읽기 경로만 건드립니다. 벤치마크 수익률을 테이블에 적어두지 않고 조회 시점에 가격에서 계산하기 때문에, 과거 데이터를 소급 재계산할 필요가 없었습니다. 파생값을 저장하지 않으면 정의를 고칠 때 마이그레이션이 필요 없습니다.
부록 3: 코스닥 벤치마크 글과의 차이
코스닥 벤치마크를 코스피200으로 잡으면 생기는 일은 자가 아예 없어서 생긴 문제였습니다. 코스닥 종목을 평가할 지수 데이터가 시스템에 존재하지 않아 전부 코스피 지수로 계산되고 있었던 도구의 결함입니다. 이번은 다릅니다. 자는 있었고 정확했고 잘 작동했지만, 그 자가 재려는 대상과 맞지 않았습니다. 코스피200 ETF의 +33.97%는 완벽하게 옳은 숫자이고, 코스닥을 80% 들고 있는 포트폴리오의 기준선이 아니었을 뿐입니다. 첫 번째는 데이터를 채워서 고치고 두 번째는 무엇과 비교할지 다시 생각해서 고칩니다. 후자가 더 자주, 더 눈에 띄지 않게 일어납니다.
이 글에서 고친 것 1개
- 2026-09-12 — 처음 발행본은 “이 글 하단의 자동 검증에 그 쿼리가 그대로 들어 있습니다”라고 썼습니다. 공개 페이지에는 없습니다. 대조 항목은 초안에만 있고 발행 때 제거됩니다. 내부 대조와 독자의 재현은 다른 약속인데 하나처럼 썼습니다.
이 사이트의 수치는 주 1회 DB와 다시 대조하고, 판단이 바뀌면 지우지 않고 글 안에 덧붙입니다. 갱신은 RSS로 받을 수 있습니다.