퀀트 실전 ⑤ — 평균-분산 최적화, 가장 유명한 공식이 실전에서 지는 이유
평균-분산 최적화는 자산들의 기대수익과 변동성, 상관관계를 넣으면 같은 위험에서 수익이 가장 높은 비중을 계산해 주는 방법입니다. 해리 마코위츠가 1952년에 내놓았고, 이 아이디어로 노벨 경제학상을 받았습니다. 현대 포트폴리오 이론이라는 말이 여기서 나왔습니다.
자산 배분 글과 상관관계 글에서 “섞으면 위험이 가중평균보다 낮아진다”는 것을 확인했습니다. 평균-분산 최적화는 그 원리를 끝까지 밀어붙여 가장 잘 섞는 비율을 공식으로 찾습니다.
그런데 이 공식은 실전에서 평판이 좋지 않습니다. 이번 글은 왜 그런지 숫자로 따라가 봅니다. 코드는 mean_variance.py에 있고, 같은 폴더에 all_weather.py, asset_allocation_basics.py, value_factor.py를 함께 두어야 돌아갑니다.
재료
올웨더 글에서 쓴 미국 자산 네 개입니다. 1972년 1월부터 2020년 7월까지 583개월입니다. 무위험 금리로는 Fama-French 3팩터 파일의 월별 무위험 금리(RF)를 썼습니다. 원 출처는 Kenneth French Data Library이고, 코드는 이 파일의 공개 사본을 읽습니다. 그 사본이 2020년 7월에 끝나서 분석도 거기서 잘랐습니다.
이 글의 성과 표에 나오는 수익률은 월별 수익률을 복리로 이은 연복리(CAGR)입니다. 산술평균을 쓴 곳은 따로 표시했습니다.
| 자산 | 연복리(CAGR) | 연변동성 | 샤프 | MDD |
|---|---|---|---|---|
| 주식 (S&P 500 총수익) | 10.52% | 12.67% | 0.50 | −49.0% |
| 장기채 | 7.98% | 10.55% | 0.36 | −21.7% |
| 중기채 (10년물) | 7.33% | 6.94% | 0.41 | −14.8% |
| 금 | 8.05% | 17.66% | 0.27 | −62.1% |
상관계수에서 하나가 눈에 띕니다. 장기채와 중기채의 상관이 0.99입니다. 사실상 같은 자산을 크기만 다르게 들고 있는 셈입니다. 나머지 조합은 전부 0에 가깝습니다. 이 0.99가 뒤에서 문제를 일으킵니다.
다만 이 0.99에는 데이터를 만든 방식 탓도 큽니다. 올웨더 글에서 밝혔듯 장기채는 20년물 금리 대신 실러 자료의 10년물 금리로 만기 20년 채권을 평가한 근사치이고, 중기채도 같은 금리로 평가한 10년 만기 채권입니다. 두 채권이 같은 금리 하나에서 나왔으니, 실제 20년물과 10년물 국채로 계산하면 상관이 이보다는 낮을 것입니다. 또 실러 자료의 주가·금리와 LBMA 금 가격은 모두 그달의 평균값이라, 변동성과 낙폭이 월말 값으로 잴 때보다 작게 나옵니다.
효율적 투자선 그리기
평균-분산 최적화는 보통 수치 최적화 라이브러리로 풉니다. 여기서는 더 단순하게 했습니다. 네 자산이면 비중을 1% 간격으로 가능한 조합을 전부 늘어놓아도 17만 6,851개입니다. 전부 계산해서 그중에서 고릅니다.
def simplex_grid(step=0.01):
"""비중 합이 1 인 모든 조합 (공매도 없음)."""
k = int(round(1 / step))
return np.array([(a, b, c, k - a - b - c)
for a in range(k + 1)
for b in range(k + 1 - a)
for c in range(k + 1 - a - b)]) / k
W = simplex_grid() # (176851, 4)
port_mean = W @ mu # 조합별 기대수익
port_vol = np.sqrt(np.einsum("ij,jk,ik->i", W, cov, W)) # 조합별 변동성
min_var = W[np.argmin(port_vol)]
max_sharpe = W[np.argmax((port_mean - rf) / port_vol)]
scipy 없이 numpy만으로 돌아가고, 무엇을 하는지 눈으로 확인할 수 있다는 장점이 있습니다.

회색 점 하나하나가 비중 조합입니다. 왼쪽 위 가장자리를 잇는 파란 선이 효율적 투자선입니다. 그 선 위의 포트폴리오는 같은 변동성에서 더 높은 수익을 낼 방법이 없습니다. 선 아래의 점들은 전부 손해 보는 조합입니다.
선 위에서 두 점이 특별합니다. 변동성이 가장 낮은 최소분산 포트폴리오와, 변동성 한 단위당 초과수익(무위험 금리를 넘는 수익)이 가장 큰 최대샤프 포트폴리오입니다.
| 비중 (주식/장기채/중기채/금) | 연복리(CAGR) | 연변동성 | 샤프 | MDD | |
|---|---|---|---|---|---|
| 최소분산 | 20 / 0 / 69 / 11 | 8.38% | 5.85% | 0.64 | −10.9% |
| 최대샤프 | 35 / 0 / 51 / 14 | 8.99% | 6.28% | 0.69 | −13.7% |
| 균등 1/N | 25 / 25 / 25 / 25 | 9.03% | 7.05% | 0.63 | −15.2% |
| 60/40 | 60 / 0 / 40 / 0 | 9.50% | 8.19% | 0.60 | −27.0% |
최대샤프가 1등입니다. 당연합니다. 샤프가 가장 높은 조합을 고른 것이니까요. 이 표는 1972년부터 2020년까지를 다 본 다음 고른 비중이라, 1972년의 투자자는 이 비중을 알 수 없었습니다. 워크포워드 글에서 본 “다 보고 나서 고른 1등”과 같은 구조입니다.
입력을 조금만 흔들면
평균-분산 최적화의 입력은 두 가지입니다. 기대수익과 공분산(변동성과 상관관계)입니다. 기대수익을 조금 바꿔 봅니다.
| 바꾼 것 | 최대샤프 비중 (주식/장기채/중기채/금) |
|---|---|
| 기준 | 35 / 0 / 51 / 14 |
| 주식 연 −1%p | 31 / 0 / 54 / 15 |
| 주식 연 +1%p | 39 / 0 / 48 / 13 |
| 금 연 +1%p | 34 / 0 / 50 / 16 |
| 금 연 −1%p | 36 / 0 / 53 / 11 |
| 장기채 연 +0.5%p | 43 / 41 / 0 / 16 |
| 중기채 연 −0.5%p | 45 / 38 / 0 / 17 |
주식과 금은 기대수익을 1%p씩 바꿔도 비중이 몇 %p 움직이는 정도입니다. 그런데 장기채의 기대수익을 연 0.5%p만 올리면 중기채 51%가 통째로 사라지고 장기채 41%가 생깁니다.
이유는 상관 0.99입니다. 두 자산이 거의 같으니 최적화는 둘 중 조금이라도 나은 쪽에 몰아줍니다. 스위치처럼 동작합니다. 주식과 금은 다른 자산과 상관이 낮아서 대체재가 없고, 그래서 비중이 덜 흔들립니다.
그럼 0.5%p는 큰 차이일까요. 48년 데이터로 계산한 장기채와 중기채의 산술평균(연율) 차이는 +0.92%p이고, 그 표준오차가 0.54%p입니다. 이것만 보면 0.5%p는 오차 범위 안의 차이 같습니다. 그런데 두 채권은 같은 금리로 함께 움직여서, 최적화가 실제로 비교하는 ‘변동성을 감안한 상대 성과’는 이보다 훨씬 정확하게 추정됩니다. 장기채를 중기채의 1.5배짜리로 보고 남는 수익 차이는 표준오차가 연 0.19%p뿐이라, 0.5%p는 그 두 배가 넘습니다. 아래 부트스트랩에서도 장기채 비중은 다시 뽑은 역사의 99%에서 0%였고, 이 스위치는 거의 일어나지 않았습니다. 그러니 이 예는 데이터가 모르는 차이라기보다, 비슷한 두 자산 사이에서 최적화가 입력에 얼마나 극단적으로 반응하는지를 보여 줍니다. 데이터가 정말 잘 모르는 것은 주식과 금의 기대수익이고, 그 흔들림은 아래에서 봅니다.
역사를 다시 뽑으면
몬테카를로 글에서 쓴 부트스트랩을 여기에도 씁니다. 583개월을 복원추출로 다시 뽑아 “있을 법한 다른 역사”를 500개 만들고, 각각에서 최소분산과 최대샤프 비중을 다시 구합니다.

| 최소분산 (5%~95%) | 최대샤프 (5%~95%) | |
|---|---|---|
| 주식 | 16% ~ 24% | 19% ~ 58% |
| 장기채 | 0% ~ 0% | 0% ~ 0% |
| 중기채 | 63% ~ 74% | 25% ~ 69% |
| 금 | 8% ~ 15% | 1% ~ 27% |
| 자산별 범위 폭 평균 | 6%p | 27%p |
최소분산은 어떤 역사를 뽑아도 비중이 거의 같습니다. 최대샤프는 주식 비중만 봐도 19%에서 58%까지 오갑니다. 같은 방법, 같은 성질의 데이터인데 답이 네 배 넘게 흔들립니다.
왜 한쪽만 흔들리나
두 포트폴리오의 차이는 하나입니다. 최소분산은 기대수익을 쓰지 않습니다. 공분산만 봅니다. 최대샤프는 기대수익과 공분산을 둘 다 씁니다.
그리고 이 둘은 추정하기 어려운 정도가 전혀 다릅니다.
| 자산 | 48년 산술평균 (연율) | 95% 신뢰구간 |
|---|---|---|
| 주식 | 10.86% | 7.3% ~ 14.4% |
| 장기채 | 8.25% | 5.3% ~ 11.2% |
| 중기채 | 7.33% | 5.4% ~ 9.3% |
| 금 | 9.24% | 4.3% ~ 14.2% |
이 표는 월평균에 12를 곱한 산술평균이라, 맨 앞 표의 연복리(CAGR)와 숫자가 다릅니다. 변동성이 크면 복리 수익률이 산술평균보다 낮아지기 때문이고, 그래서 변동성이 가장 큰 금에서 두 숫자의 차이(9.24% 대 8.05%)가 가장 큽니다.
48년치 데이터를 쓰고도 주식의 기대수익은 “7%에서 14% 사이 어딘가”라는 것까지만 말할 수 있습니다. 금은 4%에서 14%입니다. 이 구간 안의 어느 값을 넣느냐에 따라 최대샤프의 답은 완전히 달라집니다.
반면 변동성은 같은 데이터로 상대 오차 3% 안팎으로 잡힙니다. 주식 변동성 12.67%라면 ±0.4%p 수준입니다. 변동성은 매달의 흔들림 하나하나가 정보가 되지만, 평균은 긴 시간을 기다려야 한 점의 정보가 쌓이기 때문입니다.
그래서 평균-분산 최적화를 두고 “추정 오차 최대화기”라는 말이 나옵니다. 최적화는 기대수익이 높게 추정된 자산에 비중을 몰아주는데, 높게 추정된 이유 중 상당 부분은 운입니다. 결국 최적화는 운이 가장 좋았던 자산을 골라내는 장치가 됩니다.
미래를 모르고 써 보면
이제 실제로 운용한다고 해 봅니다. 매년 1월에 직전 10년(120개월) 데이터로 비중을 정하고, 그 비중으로 1년을 운용하고, 다음 해에 다시 정합니다. 10년이 쌓인 1982년부터 2020년 7월까지 463개월입니다.

| 연복리(CAGR) | 연변동성 | 샤프 | MDD | 연 회전율 | |
|---|---|---|---|---|---|
| 최소분산 | 8.41% | 5.51% | 0.84 | −8.2% | 3% |
| 최대샤프 | 8.14% | 9.24% | 0.50 | −26.9% | 14% |
| 균등 1/N | 8.77% | 6.29% | 0.79 | −12.7% | 0% |
| 60/40 | 10.49% | 7.96% | 0.84 | −27.0% | 0% |
사후에는 1등이던 최대샤프가 샤프 꼴찌입니다. 0.69가 0.50이 됐습니다. 사후 최적 비중의 변동성은 6.28%였는데, 미래를 모르고 운용하니 9.24%가 나왔습니다. 수익률은 최소분산보다도 낮습니다.
해마다 고른 비중을 보면 이유가 보입니다.
| 연도 | 최대샤프가 고른 비중 (주식/중기채/금) | 그해 최대샤프 | 그해 최소분산 |
|---|---|---|---|
| 1982 | 0 / 0 / 100 | +8.5% | +31.1% |
| 1983 | 0 / 0 / 100 | −12.8% | +5.9% |
| 1984 | 56 / 0 / 44 | −5.3% | +11.0% |
| 1985 | 100 / 0 / 0 | +31.4% | +26.0% |
| 2011 | 4 / 44 / 52 | +16.3% | +13.2% |
| 2013 | 22 / 44 / 34 | −8.1% | −1.7% |
1982년의 직전 10년(1972~1981)은 금이 온스당 수십 달러에서 수백 달러로 오른 시기입니다. 최대샤프는 그 10년을 보고 금에 100%를 걸었습니다. 그 뒤 금은 20년 가까이 약세였고, 1983년에 −12.8%가 나왔습니다. 같은 해 최소분산은 +5.9%였습니다.
2000년대 금 강세를 본 뒤인 2009~2013년에도 금 비중을 34~52%까지 올렸고, 2013년 금 폭락에서 −8.1%를 냈습니다. 39년 중 13년은 한 자산에 70% 이상을 몰았습니다.
최대샤프는 직전 10년의 승자를 따라가는 전략이 되어 버렸습니다. 모멘텀처럼 들리지만 10년 단위의 승자는 오히려 되돌아오는 경향이 있어서, 여기서는 불리하게 작동했습니다.
최소분산은 같은 39년 동안 주식 12~32%, 중기채 50~76% 사이에서만 움직였습니다. 회전율이 연 3%로 최대샤프의 5분의 1입니다.
다중팩터 글에서 팩터 다섯 개로 같은 실험을 했을 때도 최대샤프는 균등 비중에 졌습니다. 자산을 바꿔도 결론이 같습니다.
이 결과를 과하게 믿으면 안 되는 이유
두 가지를 짚어야 합니다.
첫째, 1982~2020년은 채권의 황금기였습니다. 미국 10년물 금리가 1981년 15% 근처에서 2020년 0%대로 내려오는 동안 채권 가격은 계속 올랐습니다. 중기채를 60% 넘게 담은 최소분산이 좋아 보이는 데는 이 순풍이 큽니다. 60/40의 성적에도 이 순풍이 들어 있습니다.
둘째, 데이터가 2020년 7월에서 끝납니다. 2022년에 미국 채권은 수십 년 만의 큰 손실을 냈습니다. 채권 비중이 큰 최소분산은 그해를 버티지 못했을 가능성이 큽니다. 최소분산은 “과거에 변동성이 낮았던 자산”을 고르는 것이지, 앞으로도 낮을 거라는 보장은 없습니다. 상관관계도 바뀝니다. 이 데이터에서 주식과 채권의 상관은 0이었지만, 2022년에는 둘이 같이 떨어졌습니다.
그래서 이 글의 결론은 “최소분산을 쓰세요”가 아닙니다.
정리하면
- 평균-분산 최적화는 이론적으로 가장 잘 섞는 비율을 줍니다. 단, 입력이 정확하다면입니다.
- 기대수익은 48년 데이터로도 주식이 7%~14% 범위라 정확하게 알 수 없습니다. 변동성은 훨씬 정확하게 잡힙니다.
- 기대수익을 쓰는 최대샤프는 입력을 조금만 바꿔도 비슷한 자산 사이에서 스위치처럼 넘어가고, 역사를 다시 뽑으면 비중이 27%p씩 흔들립니다. 기대수익을 쓰지 않는 최소분산은 6%p입니다.
- 미래를 모르고 운용하면 사후 1등이던 최대샤프가 샤프 꼴찌가 됩니다. 직전 10년 승자를 쫓다가 1983년 금, 2013년 금에서 크게 잃었습니다.
- 실전에서 쓸 수 있는 것은 공식의 분산 쪽 절반입니다. 그마저도 과거의 변동성과 상관이 이어진다는 가정 위에 서 있습니다.
다음 글에서는 이 방향으로 한 걸음 더 갑니다. 기대수익을 아예 쓰지 않고 각 자산이 포트폴리오 위험에 기여하는 몫을 똑같이 맞추는 리스크 패리티입니다. 올웨더 글에서 전체 기간 데이터로 한 번 구해 봤던 비중을 매달 다시 계산하고, 레버리지까지 얹어 봅니다.
2026-09-28 수정: 최대샤프 포트폴리오의 정의를 “무위험 금리 대비 수익이 가장 좋은 조합”에서 “변동성 한 단위당 초과수익이 가장 큰 조합”으로 바로잡고, 장기채·중기채의 차이 +0.92%p가 산술평균(연율)이라는 점을 밝혔으며, “60/40이 연평균 1등인 것도 채권 순풍 때문”이라고 한 문장을 “60/40의 성적에도 이 순풍이 들어 있다”로 고쳤습니다.
2026-10-22 수정: 장기채·중기채 상관 0.99가 같은 금리로 두 채권을 만든 방식에서 크게 나온다는 점과 월평균 가격의 한계를 밝히고, 0.5%p를 “48년치 데이터가 구분하지 못하는 차이”라고 한 문단을 부트스트랩 결과(재표본의 99%에서 장기채 비중 0%)에 맞게 고쳤으며, 부트스트랩 표에 장기채 행을 넣었습니다.
참고 자료
- Markowitz, H. (1952). Portfolio Selection. Journal of Finance, 7(1).
이 글은 학습과 정보 공유 목적으로 작성되었으며, 특정 종목이나 상품에 대한 투자 권유가 아닙니다. 본문의 수익률은 거래비용과 세금을 반영하지 않은 과거 데이터이며 미래 성과를 보장하지 않습니다. 투자의 판단과 책임은 투자자 본인에게 있습니다.