Skip to content
Published on

자산 배분 완전 가이드: 포트폴리오 전략부터 리밸런싱까지

Authors

목차

  1. 자산 배분의 기본 원칙
  2. 주요 자산군 특성 분석
  3. 자산 배분 전략 유형
  4. 한국 투자자를 위한 자산 배분
  5. 리밸런싱 전략
  6. Python 포트폴리오 최적화
  7. 퀴즈 및 자기 점검

1. 자산 배분의 기본 원칙

자산 배분이란 무엇인가

자산 배분(Asset Allocation)은 투자 목표와 위험 허용 범위에 맞게 포트폴리오를 여러 자산군에 분산 투자하는 과정입니다. 단순히 "달걀을 한 바구니에 담지 마라"는 격언을 실천하는 것이지만, 그 안에는 수십 년간의 금융 이론과 실증 연구가 담겨 있습니다.

투자 수익의 약 90% 이상은 어떤 종목을 선택하느냐가 아니라 어떤 자산군에 얼마를 배분하느냐에 의해 결정된다는 연구 결과(브린슨, 후드, 비바워 1986년 연구)는 자산 배분의 중요성을 잘 보여줍니다.

현대 포트폴리오 이론 (MPT)

1952년 해리 마코위츠(Harry Markowitz)가 발표한 현대 포트폴리오 이론(Modern Portfolio Theory, MPT)은 투자 이론의 근간을 이루고 있습니다. 이 이론의 핵심 주장은 다음과 같습니다.

분산 투자의 수학적 근거

두 자산 A, B가 있을 때 포트폴리오의 기대 수익률과 분산은 다음과 같이 계산됩니다.

  • 기대 수익률: E(Rp) = wA * E(RA) + wB * E(RB)
  • 포트폴리오 분산: Var(Rp) = wA^2 * Var(RA) + wB^2 * Var(RB) + 2 * wA * wB * Cov(RA, RB)

여기서 두 자산의 상관계수(ρ)가 낮을수록 포트폴리오의 위험이 줄어드는 분산 효과가 커집니다. 상관계수가 1.0이면 분산 효과가 없고, -1.0이면 완전한 헤지가 가능합니다.

마코위츠의 핵심 통찰

동일한 수익률이라면 위험이 낮은 포트폴리오가 우월하고, 동일한 위험이라면 수익률이 높은 포트폴리오가 우월합니다. 이런 포트폴리오들의 집합을 **효율적 프론티어(Efficient Frontier)**라고 합니다.

효율적 프론티어 개념

효율적 프론티어는 주어진 위험 수준에서 최대 기대 수익률을 제공하는 포트폴리오들의 집합입니다. 이 곡선 위에 있지 않은 포트폴리오는 비효율적입니다. 즉, 같은 위험을 감수하면서 더 낮은 수익을 얻거나, 같은 수익을 얻으면서 더 많은 위험을 감수하는 상태입니다.

무위험 자산(국채 등)을 포트폴리오에 포함시키면 자본시장선(Capital Market Line, CML)이 형성됩니다. CML은 무위험 수익률에서 시작해 시장 포트폴리오(시장 전체를 반영하는 포트폴리오)에 접하는 접선으로, 이 선 위의 포트폴리오가 모든 위험 포트폴리오보다 우월합니다.

위험-수익 트레이드오프

투자에서 위험과 수익은 반드시 함께 움직입니다. 더 높은 수익을 원한다면 더 높은 위험을 감수해야 합니다. 이를 **위험-수익 트레이드오프(Risk-Return Tradeoff)**라고 합니다.

투자자는 자신의 위험 허용 능력(Risk Tolerance)과 위험 감수 의지(Risk Appetite)에 맞는 포트폴리오를 선택해야 합니다. 위험 허용 능력은 재무적으로 손실을 감당할 수 있는 능력이고, 위험 감수 의지는 심리적으로 손실을 견딜 수 있는 능력입니다.


2. 주요 자산군 특성 분석

주식 (Equity)

주식은 기업의 소유권을 나타내는 증권으로, 장기적으로 가장 높은 수익을 제공하는 자산군입니다.

국내 주식 (한국 시장)

  • 코스피(KOSPI): 시가총액 기준 상위 기업들로 구성, 삼성전자 등 대형주 포함
  • 코스닥(KOSDAQ): 성장성 높은 중소형 기술기업 위주
  • 특성: 수출 의존도 높음, 반도체/자동차/화학 섹터 비중 큼, 신흥국 특성상 변동성 높음

해외 주식

선진국 주식:

  • 미국 S&P 500: 미국 대형주 500개, 글로벌 최대 자본 시장
  • 미국 나스닥: 기술주 중심, 높은 성장성과 변동성
  • 유럽 주식: 가치주 성향, 낮은 밸류에이션, 배당 중시
  • 일본 주식: 기업 지배구조 개선 중, 엔화 약세 수혜

신흥국 주식:

  • 중국: 세계 2위 경제, 기술주 규제 리스크 존재
  • 인도: 높은 성장 잠재력, 인구 구조 유리
  • 동남아: 베트남, 인도네시아 등 성장 스토리
  • 특성: 높은 성장성, 높은 변동성, 통화 리스크

채권 (Fixed Income)

채권은 정해진 이자를 지급하는 확정 수익 자산으로, 포트폴리오의 안정성을 높이는 역할을 합니다.

국채 (Government Bonds)

  • 한국 국채: 안전자산, 낮은 수익률, 세금 혜택
  • 미국 국채(Treasury): 전 세계 안전자산의 기준, 달러 강세 시 유리
  • 장기채 vs 단기채: 장기채는 금리 위험이 높지만 수익률도 높음

회사채 (Corporate Bonds)

  • 투자등급(Investment Grade): BBB 이상, 안전하지만 낮은 수익률
  • 하이일드(High Yield): BB 이하, 높은 수익률과 위험
  • 주식과 상관관계가 높아 분산 효과 제한적

물가연동채 (TIPS, Treasury Inflation-Protected Securities)

  • 원금이 소비자물가지수(CPI)에 연동
  • 인플레이션 헤지 기능
  • 실질 금리가 낮아지면 가격 상승

대안투자 (Alternative Investments)

리츠 (REITs, Real Estate Investment Trusts)

  • 부동산을 주식처럼 거래할 수 있는 간접 투자 수단
  • 임대 수익 기반의 안정적 현금흐름
  • 주식/채권과 낮은 상관관계로 분산 효과
  • 인플레이션 헤지 기능 (임대료는 인플레이션 반영)
  • 한국 리츠: 맥쿼리인프라, 롯데리츠 등

금 (Gold)

  • 전통적인 안전자산, 인플레이션 헤지
  • 달러 약세 시 가격 상승 경향
  • 주식 시장 위기 시 상관관계 낮아짐
  • 배당/이자 없음, 보관 비용 발생 (ETF 활용으로 해결)

원자재 (Commodities)

  • 구리: 경기 선행 지표 (닥터 코퍼)
  • 원유: 에너지 가격의 기준
  • 농산물: 식료품 물가에 영향
  • 인플레이션 헤지 기능, 높은 변동성

인프라 (Infrastructure)

  • 도로, 철도, 공항, 에너지 파이프라인 등
  • 안정적인 현금흐름, 장기 계약 기반
  • 인플레이션 연동 수익 구조

현금성 자산 (Cash Equivalents)

  • 예금, MMF, 단기 국채 등
  • 원금 보전, 유동성 확보
  • 기회비용: 인플레이션 시 실질 수익률 마이너스 가능
  • 포트폴리오에서 리밸런싱 재원 및 비상 자금 역할

3. 자산 배분 전략 유형

전략적 자산 배분 (SAA) vs 전술적 자산 배분 (TAA)

전략적 자산 배분 (Strategic Asset Allocation)

장기적인 목표 비율을 설정하고 이를 유지하는 방식입니다.

  • 투자 기간, 목표 수익률, 위험 허용 범위를 기반으로 설정
  • 시장 상황에 관계없이 목표 비율을 유지
  • 장점: 단순성, 규율 있는 투자, 낮은 거래 비용
  • 단점: 시장 기회를 활용하지 못함

예시 포트폴리오 (60/40):

  • 주식 60%: 국내 주식 20% + 미국 주식 30% + 신흥국 주식 10%
  • 채권 40%: 국내 채권 20% + 미국 국채 20%

전술적 자산 배분 (Tactical Asset Allocation)

단기적인 시장 상황에 따라 자산 비율을 조정하는 방식입니다.

  • 전략적 배분을 기본으로 하되 ±10~20% 범위 내에서 조정
  • 경기 사이클, 밸류에이션, 기술적 분석 활용
  • 장점: 시장 기회 활용, 하방 리스크 관리
  • 단점: 높은 거래 비용, 타이밍 실패 위험

생애주기 자산 배분

나이에 따라 위험 자산 비율을 줄여가는 전략입니다.

연령 공식

일반적인 규칙: 주식 비율 = 100 - 나이

현대적 규칙 (기대수명 증가 반영): 주식 비율 = 110 - 나이 또는 120 - 나이

예시:

  • 30세: 주식 8090%, 채권 1020%
  • 40세: 주식 7080%, 채권 2030%
  • 50세: 주식 6070%, 채권 3040%
  • 60세: 주식 4050%, 채권 5060%

Target Date Fund (TDF)

목표 은퇴 시기에 맞춰 자동으로 자산 배분을 조정하는 펀드입니다. 한국에서는 2016년부터 퇴직연금 디폴트옵션으로 도입되어 확산 중입니다.

영구 포트폴리오 (Permanent Portfolio)

해리 브라운(Harry Browne)이 고안한 4등분 포트폴리오입니다.

자산비율유리한 경제 환경
주식25%경제 성장기
장기 국채25%디플레이션, 경기 침체
25%인플레이션, 달러 약세
현금(단기채)25%경기 침체, 디플레이션

어떤 경제 환경에서도 최소한 하나의 자산이 잘 작동하도록 설계되어 있습니다. 변동성이 낮고 심리적으로 편안한 포트폴리오지만, 강세장에서는 100% 주식 포트폴리오에 비해 수익이 낮습니다.

올웨더 포트폴리오 (All Weather Portfolio)

레이 달리오(Ray Dalio)의 브리지워터 어소시에이츠가 개발한 포트폴리오입니다. 경제 환경을 성장/위축 × 인플레이션/디플레이션의 4가지 조합으로 분류하고 각각을 커버합니다.

자산비율
미국 주식30%
장기 미국 국채 (20년 이상)40%
중기 미국 국채 (7~10년)15%
7.5%
원자재7.5%

리스크 패리티(Risk Parity) 개념을 활용해 각 자산의 위험 기여도를 동등하게 설계합니다. 장기채 비중이 높아 금리 상승기에는 취약합니다.

코어-새틀라이트 전략 (Core-Satellite Strategy)

포트폴리오를 두 부분으로 나누는 전략입니다.

코어 (Core) - 70~80%

  • 시장 지수를 추종하는 저비용 인덱스 펀드/ETF
  • 목표: 시장 수익률 확보, 비용 최소화
  • 예: KODEX 200, SPY, VTI, VXUS

새틀라이트 (Satellite) - 20~30%

  • 초과 수익을 위한 액티브 투자
  • 섹터 ETF, 테마 ETF, 개별 종목, 대안 자산
  • 예: 반도체 ETF, 클린에너지 ETF, 개별 성장주

4. 한국 투자자를 위한 자산 배분

국내 ETF 활용 포트폴리오

주요 국내 ETF

주식 ETF:

  • KODEX 200: 코스피 200 추종, 가장 거래량 많음
  • TIGER 200: KODEX 200과 유사, 약간 낮은 운용보수
  • KBSTAR 200: KB자산운용 운용
  • KODEX 코스닥150: 코스닥 성장주 투자
  • TIGER 미국S&P500: 미국 S&P 500 추종
  • KODEX 미국나스닥100: 나스닥 100 추종

채권 ETF:

  • KODEX 국채10년: 10년 만기 한국 국채
  • TIGER 국채3년: 단기 안정형 채권
  • KODEX 단기채권PLUS: 초단기 채권 파킹형

대안 자산 ETF:

  • TIGER 200 리츠부동산인프라: 국내 리츠 + 인프라
  • KODEX 골드선물(H): 금 선물 환헤지형
  • TIGER 골드선물(H): 금 선물 환헤지형

포트폴리오 예시 (국내 ETF 중심)

보수적 포트폴리오:

  • KODEX 200: 20%
  • TIGER 미국S&P500: 15%
  • KODEX 국채10년: 35%
  • TIGER 국채3년: 15%
  • KODEX 골드선물(H): 10%
  • 현금(MMF): 5%

성장형 포트폴리오:

  • KODEX 200: 25%
  • TIGER 미국S&P500: 25%
  • KODEX 미국나스닥100: 10%
  • TIGER 신흥국MSCI: 10%
  • KODEX 국채10년: 15%
  • TIGER 골드선물(H): 7.5%
  • KODEX 원자재선물: 7.5%

해외 ETF 활용

미국 상장 ETF 주요 종목

주식:

  • SPY / IVV / VOO: S&P 500 (운용보수 차이 주의, VOO 최저)
  • QQQ: 나스닥 100
  • VTI: 미국 전체 시장
  • VXUS / VEU: 미국 제외 전세계
  • VWO: 신흥국 주식
  • VEA: 선진국 (미국 제외)

채권:

  • BND: 미국 채권 전체
  • TLT: 20년 이상 미국 장기 국채
  • IEF: 7~10년 미국 중기 국채
  • TIP: 물가연동채 (TIPS)
  • EMB: 신흥국 달러채권

대안:

  • GLD / IAU: 금 ETF (IAU가 운용보수 더 낮음)
  • VNQ: 미국 리츠
  • DJP / PDBC: 원자재

운용보수 비교 (중요!)

ETF추종 지수운용보수(%)
VOOS&P 5000.03
SPYS&P 5000.09
VTI미국 전체0.03
QQQ나스닥 1000.20
IAU0.25
GLD0.40

운용보수는 장기 투자에서 복리 효과로 인해 큰 차이를 만듭니다. 30년 투자 시 0.1% 차이가 수십만 원의 차이로 이어질 수 있습니다.

환헤지 vs 환노출 전략

해외 자산에 투자할 때 환율 변동이 수익에 영향을 줍니다.

환노출 (Unhedged)

  • 달러 강세 시 추가 수익 (원화 약세)
  • 달러 약세 시 수익 감소 (원화 강세)
  • 헤지 비용 없음 → 장기적으로 유리
  • 미국 ETF(SPY, VTI 등) 직접 투자

환헤지 (Hedged)

  • 환율 변동 위험 제거
  • 헤지 비용 발생 (연 0.5~1% 수준)
  • 국내 상장 환헤지 ETF: TIGER 미국S&P500(H), KODEX 미국나스닥100(H)
  • 단기 투자자에게 유리, 장기 투자자에게는 비용 손실

권장 전략

장기 투자자: 환노출 투자 권장 (헤지 비용 절감) 단기 투자자: 환율 변동성 크면 환헤지 고려 분산 차원: 환노출과 환헤지 혼합 활용

ISA/IRP 계좌 내 자산 배분 최적화

ISA (Individual Savings Account, 개인종합자산관리계좌)

  • 일반형 / 서민형 / 농어민형 구분
  • 연간 납입 한도: 2,000만 원 (총 한도 1억 원)
  • 비과세 혜택: 일반형 200만 원, 서민형 400만 원
  • 200만 원 초과분은 9.9% 분리과세
  • 3년 의무 보유

ISA 내 최적 자산:

  • 세금 효율 위해 배당 수익률 높은 자산 우선 배치
  • 리츠 ETF, 고배당 ETF, 채권 ETF
  • KODEX 200, TIGER 미국S&P500 등

IRP (Individual Retirement Pension, 개인형 퇴직연금)

  • 연간 납입 세액공제 한도: 900만 원 (연금저축 포함)
  • 세액공제율: 소득 5,500만 원 이하 16.5%, 초과 13.2%
  • 55세 이후 연금 수령 시 3.3~5.5% 저율과세
  • 위험자산 비중 한도: 70% (안전자산 30% 이상 의무)

IRP 내 추천 ETF:

  • TDF(Target Date Fund): 생애주기에 맞는 자동 배분
  • KODEX 200: 국내 주식 코어
  • TIGER 미국S&P500: 해외 주식 코어
  • KODEX 국채10년: 안전자산 의무 비율 충족

5. 리밸런싱 전략

리밸런싱이란

포트폴리오의 자산 비율이 목표 비율에서 벗어났을 때 다시 원래 비율로 조정하는 과정입니다. 주가 상승으로 주식 비율이 높아지면 주식을 팔고 채권을 사는 식입니다.

왜 리밸런싱이 필요한가

  1. 위험 관리: 주식 비중이 과도하게 높아지면 하락 시 손실 확대
  2. 규율 있는 투자: 고점에서 팔고 저점에서 사는 효과
  3. 목표 유지: 투자 목표에 맞는 위험/수익 프로파일 유지

시간 기반 리밸런싱

정해진 시간 간격으로 리밸런싱하는 방식입니다.

월별 리밸런싱

  • 장점: 목표 비율 정확히 유지
  • 단점: 높은 거래 비용, 세금 발생 빈번

분기별 리밸런싱

  • 장점: 비용과 정밀도의 균형
  • 단점: 빠른 시장 변화에 늦게 대응

연간 리밸런싱

  • 장점: 낮은 거래 비용, 세금 최소화
  • 단점: 목표 비율 크게 벗어날 수 있음

권장: 세금 절약을 위해 연 1~2회 리밸런싱이 일반적으로 최적

임계값 기반 리밸런싱 (밴드 리밸런싱)

자산 비율이 목표에서 일정 임계값을 벗어날 때만 리밸런싱합니다.

절대 임계값

  • 예: 주식 목표 60%, 임계값 ±5%
  • 주식 비율이 55% 미만이거나 65% 초과 시 리밸런싱

상대 임계값

  • 예: 목표 비율의 ±20% 이상 벗어날 때
  • 주식 목표 60%이면 48~72% 범위 이탈 시 리밸런싱

임계값 선택 기준

  • 낮은 임계값(±5%): 목표 정밀 유지, 높은 거래 비용
  • 높은 임계값(±10~20%): 낮은 거래 비용, 목표에서 더 벗어남
  • 일반적으로 ±5~10%가 합리적

리밸런싱 세금 고려사항

한국에서 주식/ETF 거래 시 세금:

  • 국내 주식/ETF: 매매 차익 비과세 (단, 금융소득 종합과세 초과 시)
  • 해외 ETF (국내 상장): 매매 차익 15.4% 분리과세
  • 미국 직접 투자: 양도소득세 22% (250만 원 공제)
  • 배당 소득: 15.4% 원천징수

세금 최소화 리밸런싱 전략:

  1. 세금 우대 계좌(ISA, IRP, 연금저축) 내에서 우선 리밸런싱
  2. 신규 매수로 비중 조정 (매도 없이 적립식으로 균형 맞추기)
  3. 손실 난 자산을 매도해 세금 상쇄 (Tax Loss Harvesting)
  4. 연말에 손익을 통산해 세금 최소화

6. Python 포트폴리오 최적화

필요 라이브러리 설치

pip install numpy pandas yfinance scipy matplotlib seaborn

기본 포트폴리오 분석

import numpy as np
import pandas as pd
import yfinance as yf
import matplotlib.pyplot as plt
from scipy.optimize import minimize
import warnings
warnings.filterwarnings('ignore')

# 자산 목록 설정 (미국 ETF 기준)
tickers = ['SPY', 'QQQ', 'BND', 'GLD', 'VNQ']
names = {
    'SPY': 'S&P 500',
    'QQQ': 'NASDAQ 100',
    'BND': '미국 채권',
    'GLD': '금',
    'VNQ': '미국 리츠'
}

# 데이터 다운로드 (최근 5년)
print("시장 데이터 다운로드 중...")
data = yf.download(tickers, start='2019-01-01', end='2024-01-01')['Adj Close']
print(f"다운로드 완료: {data.shape[0]}일치 데이터")
print(data.tail())

수익률 및 위험 계산

# 일별 수익률 계산
returns = data.pct_change().dropna()

# 연간화 파라미터
trading_days = 252

# 개별 자산 통계
print("\n=== 개별 자산 성과 분석 ===")
for ticker in tickers:
    annual_return = returns[ticker].mean() * trading_days
    annual_vol = returns[ticker].std() * np.sqrt(trading_days)
    sharpe = annual_return / annual_vol  # 무위험수익률 0 가정
    max_dd = calculate_max_drawdown(returns[ticker])
    print(f"{names[ticker]:12s}: 수익률={annual_return:.1%}, 변동성={annual_vol:.1%}, "
          f"샤프={sharpe:.2f}, 최대낙폭={max_dd:.1%}")

def calculate_max_drawdown(returns_series):
    """최대 낙폭 계산"""
    cumulative = (1 + returns_series).cumprod()
    rolling_max = cumulative.cummax()
    drawdown = (cumulative - rolling_max) / rolling_max
    return drawdown.min()

효율적 프론티어 계산

def portfolio_performance(weights, mean_returns, cov_matrix):
    """
    포트폴리오 성과 계산
    Returns: (수익률, 변동성, 샤프비율)
    """
    weights = np.array(weights)
    port_return = np.sum(mean_returns * weights) * trading_days
    port_vol = np.sqrt(
        np.dot(weights.T, np.dot(cov_matrix * trading_days, weights))
    )
    sharpe = port_return / port_vol
    return port_return, port_vol, sharpe


def generate_efficient_frontier(mean_returns, cov_matrix, num_portfolios=5000):
    """
    몬테카를로 방식으로 효율적 프론티어 근사
    """
    num_assets = len(mean_returns)
    results = np.zeros((3, num_portfolios))
    weight_records = []

    np.random.seed(42)
    for i in range(num_portfolios):
        # 랜덤 가중치 생성 (합계 = 1)
        weights = np.random.random(num_assets)
        weights /= weights.sum()
        weight_records.append(weights)

        ret, vol, sharpe = portfolio_performance(weights, mean_returns, cov_matrix)
        results[0, i] = vol      # 변동성
        results[1, i] = ret      # 수익률
        results[2, i] = sharpe   # 샤프 비율

    return results, weight_records


# 평균 수익률과 공분산 행렬
mean_returns = returns.mean()
cov_matrix = returns.cov()

# 효율적 프론티어 생성
results, weights = generate_efficient_frontier(mean_returns, cov_matrix)

# 시각화
fig, ax = plt.subplots(figsize=(12, 8))
scatter = ax.scatter(
    results[0, :],
    results[1, :],
    c=results[2, :],
    cmap='viridis',
    alpha=0.5,
    s=10
)
plt.colorbar(scatter, label='샤프 비율')
ax.set_xlabel('연간 변동성')
ax.set_ylabel('연간 기대 수익률')
ax.set_title('효율적 프론티어 (몬테카를로 시뮬레이션)')

# 최대 샤프 비율 포트폴리오 표시
max_sharpe_idx = np.argmax(results[2, :])
ax.scatter(
    results[0, max_sharpe_idx],
    results[1, max_sharpe_idx],
    marker='*',
    color='red',
    s=500,
    label='최대 샤프 비율 포트폴리오'
)
ax.legend()
plt.tight_layout()
plt.savefig('efficient_frontier.png', dpi=150)
plt.show()
print(f"최적 포트폴리오 저장 완료")

샤프 비율 최적화

def neg_sharpe(weights, mean_returns, cov_matrix, risk_free_rate=0.03):
    """최소화를 위해 음의 샤프 비율 반환"""
    ret, vol, _ = portfolio_performance(weights, mean_returns, cov_matrix)
    sharpe = (ret - risk_free_rate) / vol
    return -sharpe


def optimize_max_sharpe(mean_returns, cov_matrix, risk_free_rate=0.03):
    """최대 샤프 비율 포트폴리오 최적화"""
    num_assets = len(mean_returns)
    initial_weights = np.array([1.0 / num_assets] * num_assets)

    # 제약 조건: 가중치 합계 = 1
    constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})

    # 경계 조건: 0 <= 가중치 <= 1 (공매도 허용 안 함)
    bounds = tuple((0, 1) for _ in range(num_assets))

    result = minimize(
        neg_sharpe,
        initial_weights,
        args=(mean_returns, cov_matrix, risk_free_rate),
        method='SLSQP',
        bounds=bounds,
        constraints=constraints,
        options={'maxiter': 1000}
    )

    return result


# 최적화 실행
optimal = optimize_max_sharpe(mean_returns, cov_matrix, risk_free_rate=0.03)
optimal_weights = optimal.x

print("\n=== 최대 샤프 비율 최적 포트폴리오 ===")
for i, ticker in enumerate(tickers):
    print(f"  {names[ticker]:12s}: {optimal_weights[i]:.1%}")

opt_ret, opt_vol, opt_sharpe = portfolio_performance(
    optimal_weights, mean_returns, cov_matrix
)
print(f"\n기대 수익률: {opt_ret:.2%}")
print(f"예상 변동성: {opt_vol:.2%}")
print(f"샤프 비율:   {opt_sharpe:.3f}")

최소 분산 포트폴리오

def min_variance(weights, mean_returns, cov_matrix):
    """포트폴리오 변동성 반환"""
    _, vol, _ = portfolio_performance(weights, mean_returns, cov_matrix)
    return vol


def optimize_min_variance(mean_returns, cov_matrix):
    """최소 분산 포트폴리오 최적화"""
    num_assets = len(mean_returns)
    initial_weights = np.array([1.0 / num_assets] * num_assets)
    constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
    bounds = tuple((0, 1) for _ in range(num_assets))

    result = minimize(
        min_variance,
        initial_weights,
        args=(mean_returns, cov_matrix),
        method='SLSQP',
        bounds=bounds,
        constraints=constraints
    )
    return result


minvar = optimize_min_variance(mean_returns, cov_matrix)
minvar_weights = minvar.x

print("\n=== 최소 분산 포트폴리오 ===")
for i, ticker in enumerate(tickers):
    print(f"  {names[ticker]:12s}: {minvar_weights[i]:.1%}")

mv_ret, mv_vol, mv_sharpe = portfolio_performance(
    minvar_weights, mean_returns, cov_matrix
)
print(f"\n기대 수익률: {mv_ret:.2%}")
print(f"예상 변동성: {mv_vol:.2%}")
print(f"샤프 비율:   {mv_sharpe:.3f}")

몬테카를로 시뮬레이션

def monte_carlo_simulation(
    initial_investment,
    weights,
    mean_returns,
    cov_matrix,
    num_simulations=1000,
    num_days=252 * 10  # 10년
):
    """
    포트폴리오 미래 가치 몬테카를로 시뮬레이션
    """
    # 연간 포트폴리오 통계를 일별로 변환
    port_daily_return = np.sum(mean_returns * weights)
    port_daily_vol = np.sqrt(
        np.dot(weights.T, np.dot(cov_matrix, weights))
    )

    simulation_results = np.zeros((num_days, num_simulations))
    simulation_results[0] = initial_investment

    np.random.seed(42)
    for sim in range(num_simulations):
        for day in range(1, num_days):
            # 일별 무작위 수익률 (정규분포 가정)
            daily_return = np.random.normal(
                port_daily_return, port_daily_vol
            )
            simulation_results[day, sim] = (
                simulation_results[day - 1, sim] * (1 + daily_return)
            )

    return simulation_results


# 시뮬레이션 실행
initial_amount = 10_000_000  # 1,000만 원
sim_results = monte_carlo_simulation(
    initial_amount,
    optimal_weights,
    mean_returns,
    cov_matrix,
    num_simulations=500,
    num_days=252 * 10
)

final_values = sim_results[-1, :]

print("\n=== 10년 후 포트폴리오 가치 시뮬레이션 결과 ===")
print(f"초기 투자금:       {initial_amount:>15,}원")
print(f"중앙값 (50th):     {np.percentile(final_values, 50):>15,.0f}원")
print(f"낙관 (75th):       {np.percentile(final_values, 75):>15,.0f}원")
print(f"비관 (25th):       {np.percentile(final_values, 25):>15,.0f}원")
print(f"최악 (5th):        {np.percentile(final_values, 5):>15,.0f}원")
print(f"최선 (95th):       {np.percentile(final_values, 95):>15,.0f}원")

# 시각화
fig, axes = plt.subplots(1, 2, figsize=(16, 6))

# 시뮬레이션 경로
ax1 = axes[0]
for i in range(min(100, sim_results.shape[1])):
    ax1.plot(sim_results[:, i], alpha=0.1, linewidth=0.5, color='steelblue')
ax1.plot(np.median(sim_results, axis=1), color='red',
         linewidth=2, label='중앙값')
ax1.set_xlabel('거래일')
ax1.set_ylabel('포트폴리오 가치 (원)')
ax1.set_title('10년 몬테카를로 시뮬레이션')
ax1.legend()
ax1.yaxis.set_major_formatter(plt.FuncFormatter(
    lambda x, p: f'{x/1e6:.0f}M'
))

# 최종 가치 분포
ax2 = axes[1]
ax2.hist(final_values / 1e6, bins=50, color='steelblue', edgecolor='white')
ax2.axvline(np.percentile(final_values, 50) / 1e6,
            color='red', linestyle='--', label='중앙값')
ax2.axvline(np.percentile(final_values, 5) / 1e6,
            color='orange', linestyle='--', label='5th 백분위')
ax2.set_xlabel('최종 포트폴리오 가치 (백만 원)')
ax2.set_ylabel('빈도')
ax2.set_title('10년 후 포트폴리오 가치 분포')
ax2.legend()

plt.tight_layout()
plt.savefig('monte_carlo_simulation.png', dpi=150)
plt.show()

상관관계 히트맵

import seaborn as sns

fig, ax = plt.subplots(figsize=(8, 6))
corr_matrix = returns.corr()

# 자산명을 한글로 변환
corr_df = corr_matrix.copy()
corr_df.columns = [names[t] for t in tickers]
corr_df.index = [names[t] for t in tickers]

sns.heatmap(
    corr_df,
    annot=True,
    fmt='.2f',
    cmap='RdYlGn',
    vmin=-1,
    vmax=1,
    center=0,
    ax=ax,
    square=True
)
ax.set_title('자산간 상관관계 히트맵')
plt.tight_layout()
plt.savefig('correlation_heatmap.png', dpi=150)
plt.show()

7. 퀴즈 및 자기 점검

퀴즈 1: 현대 포트폴리오 이론의 핵심 주장은 무엇인가요?

정답: 상관관계가 낮은 여러 자산을 조합하면 개별 자산의 가중평균 위험보다 낮은 위험으로 동일한 수익률을 달성할 수 있습니다 (분산 효과).

설명: 마코위츠는 1952년 포트폴리오 이론을 통해 두 자산의 상관계수가 1보다 낮을 경우 포트폴리오를 구성하면 개별 자산보다 위험을 낮출 수 있음을 수학적으로 증명했습니다. 이것이 분산 투자의 이론적 근거이며, 효율적 프론티어의 개념으로 이어집니다.

퀴즈 2: 올웨더 포트폴리오와 영구 포트폴리오의 차이점은 무엇인가요?

정답: 영구 포트폴리오는 주식/채권/금/현금을 동일하게 25%씩 배분하는 단순한 구조인 반면, 올웨더 포트폴리오는 리스크 패리티 개념을 사용해 각 경제 환경(성장/위축 × 인플레이션/디플레이션)에 대응하도록 설계된 정교한 구조입니다.

설명: 올웨더 포트폴리오는 채권 비중이 55%(장기채 40% + 중기채 15%)로 매우 높습니다. 이는 주식의 변동성이 채권보다 훨씬 높기 때문에 위험 기여도를 동등하게 하려면 채권을 더 많이 보유해야 하기 때문입니다. 반면 영구 포트폴리오는 단순하고 이해하기 쉽다는 장점이 있습니다.

퀴즈 3: 리밸런싱 시 세금을 최소화하는 방법은 무엇인가요?

정답: (1) ISA/IRP 등 세금 우대 계좌 내에서 리밸런싱, (2) 신규 자금 매수로 비중 조정(매도 없이), (3) 손실 난 자산 매도로 세금 상쇄(Tax Loss Harvesting)

설명: 과세 계좌에서 리밸런싱 시 매도 차익에 세금이 발생합니다. 이를 최소화하려면 세금 우대 계좌를 최대한 활용하고, 월 적립식 투자 시 비중이 낮아진 자산을 더 많이 매수해 매도 없이 균형을 맞추는 방식이 효과적입니다.

퀴즈 4: 샤프 비율(Sharpe Ratio)이 높을수록 무조건 좋은 포트폴리오인가요?

정답: 아닙니다. 샤프 비율은 정규분포를 가정하지만 실제 자산 수익률은 두꺼운 꼬리(Fat Tail)를 가집니다. 또한 샤프 비율이 높더라도 최대 낙폭이 크거나 유동성이 낮으면 실제 투자에 부적합할 수 있습니다.

설명: 샤프 비율의 한계로는 (1) 수익률의 비대칭성 무시, (2) 과거 데이터 기반 미래 보장 없음, (3) 레버리지로 쉽게 조작 가능, (4) 극단적 손실 이벤트 반영 부족 등이 있습니다. 소르티노 비율(하방 변동성만 측정), 칼마 비율(최대 낙폭 기준) 등 보완 지표와 함께 활용해야 합니다.

퀴즈 5: 환헤지 ETF와 환노출 ETF 중 장기 투자자에게 어떤 것이 유리한가요?

정답: 일반적으로 환노출 ETF가 유리합니다. 장기적으로 환헤지 비용(연 0.5~1%)이 누적되어 수익을 갉아먹기 때문입니다.

설명: 환율은 장기적으로 구매력 평가(PPP)를 반영해 수렴하는 경향이 있습니다. 단기적 환율 변동은 장기 투자 수익에 큰 영향을 미치지 않지만, 환헤지 비용은 매년 확실히 발생합니다. 다만 원달러 환율이 역사적 고점 수준에 있거나 단기 투자 시에는 환헤지를 고려할 수 있습니다.


결론

자산 배분은 투자에서 가장 중요한 의사결정 중 하나입니다. 핵심 원칙을 정리하면 다음과 같습니다.

  1. 분산 투자: 상관관계 낮은 자산을 조합해 위험 대비 수익 개선
  2. 자신에게 맞는 전략: 투자 기간, 위험 허용 범위, 재무 상황에 맞는 전략 선택
  3. 낮은 비용: 운용보수가 낮은 인덱스 ETF 중심으로 구성
  4. 정기 리밸런싱: 목표 비율 유지, 세금 최소화 방법 활용
  5. 세금 효율: ISA, IRP, 연금저축 등 세금 우대 계좌 최대 활용

완벽한 포트폴리오는 없습니다. 중요한 것은 자신의 상황에 맞는 전략을 세우고, 시장의 등락에 흔들리지 않으며 꾸준히 실행하는 것입니다. 투자는 단거리 달리기가 아닌 마라톤입니다.

주의: 이 글은 교육 목적으로 작성된 것이며, 투자 조언이 아닙니다. 투자 결정은 본인의 판단과 책임하에 이루어져야 하며, 필요시 전문 투자 상담사와 상의하시기 바랍니다.