몬테카를로 시뮬레이션 투자 활용

몬테카를로 시뮬레이션이란?

몬테카를로 시뮬레이션(Monte Carlo Simulation)은 난수를 반복 생성하여 불확실한 결과의 확률 분포를 추정하는 통계 기법입니다. 투자에서는 미래 수익률의 수천~수만 가지 시나리오를 생성하여 포트폴리오의 기대 수익, 손실 확률, 최악의 시나리오를 정량적으로 분석합니다.

백테스트가 과거 데이터 한 가지 경로만 보여준다면, 몬테카를로는 “일어날 수 있었던 수천 가지 미래”를 보여줍니다. 퀀트 트레이딩에서 전략의 견고성을 검증하고, 자금 관리 규칙을 수립하는 데 핵심적인 도구입니다.

투자에서의 3가지 활용 영역

1. 포트폴리오 수익률 시뮬레이션

과거 수익률 분포를 기반으로 미래 N년간의 자산 가치 경로를 수천 번 시뮬레이션합니다. 은퇴 자금이 고갈될 확률, 목표 수익 달성 확률 등을 산출할 수 있습니다.

import numpy as np

def monte_carlo_portfolio(initial_capital, annual_return, annual_vol, 
                          years, simulations=10000):
    """
    기하 브라운 운동(GBM) 기반 포트폴리오 시뮬레이션
    """
    daily_return = annual_return / 252
    daily_vol = annual_vol / np.sqrt(252)
    days = years * 252
    
    # 랜덤 수익률 행렬 생성
    random_returns = np.random.normal(
        daily_return, daily_vol, (simulations, days)
    )
    
    # 누적 자산 경로 계산
    price_paths = initial_capital * np.cumprod(1 + random_returns, axis=1)
    
    return price_paths

# 1억 원, 연 10% 수익, 연 20% 변동성, 10년
paths = monte_carlo_portfolio(100_000_000, 0.10, 0.20, 10)
final_values = paths[:, -1]

print(f"중앙값: {np.median(final_values):,.0f}원")
print(f"하위 5%: {np.percentile(final_values, 5):,.0f}원")
print(f"원금 손실 확률: {(final_values < 100_000_000).mean()*100:.1f}%")

2. 트레이딩 전략 견고성 검증

백테스트 결과의 개별 거래를 랜덤 순서로 재배치(Trade Shuffling)하여 전략의 수익이 순서 의존적인지 검증합니다. 순서를 바꿔도 대부분 수익이면 견고한 전략, 특정 순서에서만 수익이면 과적합 가능성이 높습니다.

def shuffle_trades_mc(trades, initial_capital, simulations=5000):
    """
    trades: 개별 거래 수익/손실 리스트
    거래 순서를 랜덤으로 섞어 최종 자산 분포 생성
    """
    results = []
    trades_arr = np.array(trades)
    
    for _ in range(simulations):
        shuffled = np.random.permutation(trades_arr)
        equity = initial_capital + np.cumsum(shuffled)
        
        # MDD 계산
        peak = np.maximum.accumulate(equity)
        drawdown = (peak - equity) / peak
        max_dd = drawdown.max()
        
        results.append({
            'final_equity': equity[-1],
            'max_drawdown': max_dd,
            'profitable': equity[-1] > initial_capital
        })
    
    return results

# 백테스트에서 나온 120번의 거래 결과
trade_results = [150, -80, 200, -50, 300, ...]  # PnL 리스트
mc_results = shuffle_trades_mc(trade_results, 10_000_000)

이 기법은 백테스트 과적합 방지와 함께 사용하면 전략 검증력이 크게 높아집니다.

3. Value at Risk(VaR) 산출

VaR은 "특정 신뢰 수준에서 최대 예상 손실"을 의미합니다. 몬테카를로 VaR은 정규분포를 가정하지 않으므로 꼬리 리스크(Tail Risk)를 더 정확히 반영합니다.

def monte_carlo_var(returns, portfolio_value, confidence=0.95, 
                    days=1, simulations=10000):
    """
    몬테카를로 VaR 계산
    returns: 과거 일별 수익률 시리즈
    """
    mean = returns.mean()
    cov = returns.std()
    
    # 시뮬레이션
    simulated = np.random.normal(mean * days, cov * np.sqrt(days), simulations)
    simulated_values = portfolio_value * (1 + simulated)
    losses = portfolio_value - simulated_values
    
    var = np.percentile(losses, confidence * 100)
    cvar = losses[losses >= var].mean()  # Conditional VaR
    
    return var, cvar

# 포트폴리오 1억 원의 95% 1일 VaR
var_95, cvar_95 = monte_carlo_var(daily_returns, 100_000_000)
print(f"95% VaR: {var_95:,.0f}원")
print(f"95% CVaR: {cvar_95:,.0f}원")

시뮬레이션 정확도 높이는 4가지 기법

기법 설명 효과
팻테일 분포 사용 정규분포 대신 t-분포 또는 경험적 분포 사용 극단적 손실 시나리오 반영
변동성 클러스터링 GARCH 모델로 시간 변동 변동성 반영 현실적 변동성 패턴 재현
상관관계 구조 반영 콜레스키 분해로 다자산 상관관계 유지 분산 효과 정확히 시뮬레이션
분산 축소 기법 대칭 변량법(Antithetic Variates) 적용 적은 시뮬레이션 횟수로 높은 정확도

콜레스키 분해 다자산 시뮬레이션

def correlated_mc(means, cov_matrix, days, simulations=10000):
    """
    상관관계를 유지하는 다자산 몬테카를로
    means: 자산별 일평균 수익률
    cov_matrix: 공분산 행렬
    """
    n_assets = len(means)
    L = np.linalg.cholesky(cov_matrix)
    
    all_paths = []
    for _ in range(simulations):
        # 독립 난수 생성 후 콜레스키로 상관관계 부여
        Z = np.random.normal(0, 1, (days, n_assets))
        correlated = Z @ L.T
        
        # 수익률에 평균 추가
        returns = correlated + means
        paths = np.cumprod(1 + returns, axis=0)
        all_paths.append(paths)
    
    return np.array(all_paths)

자동매매 전략에 적용하는 실전 워크플로

  1. 백테스트 실행: 전략의 개별 거래 PnL 기록 수집
  2. 거래 셔플링 MC: 5,000~10,000회 순서 재배치로 MDD·최종 수익 분포 확인
  3. 파산 확률 산출: 계좌가 초기 자본의 50% 이하로 떨어지는 시나리오 비율 계산
  4. 포지션 사이징 결정: 파산 확률 1% 이하가 되는 최대 레버리지 역산
  5. 실전 운영 중 VaR 모니터링: 일일 VaR 초과 시 포지션 축소

이 워크플로를 MDD 제어 전략과 결합하면 자금 관리의 정량적 근거를 확보할 수 있습니다.

시뮬레이션 횟수는 몇 번이 적당할까?

용도 권장 횟수 소요 시간 (파이썬)
빠른 검증 1,000회 < 1초
전략 검증 5,000~10,000회 1~5초
정밀 VaR/CVaR 50,000~100,000회 10~30초
규제 보고용 100,000회 이상 30초~수 분

NumPy 벡터 연산을 활용하면 10만 회 시뮬레이션도 수십 초 내에 완료됩니다. for 루프 대신 행렬 연산을 사용하는 것이 핵심입니다.

마무리

몬테카를로 시뮬레이션은 "미래는 불확실하다"는 전제에서 출발하는 가장 현실적인 분석 도구입니다. 백테스트가 하나의 과거를 보여준다면, 몬테카를로는 수천 가지 가능한 미래를 펼쳐 보여줍니다.

포트폴리오 수익률 전망, 전략 견고성 검증, VaR 산출, 포지션 사이징까지 — 퀀트 투자의 거의 모든 의사결정에 활용할 수 있습니다. 파이썬과 NumPy만 있으면 누구나 구현할 수 있으니, 자신의 전략에 바로 적용해 보세요.

위로 스크롤
WordPress Appliance - Powered by TurnKey Linux