# 주식 변동성 기반 등급별 부도율 산출 — 기술 문서 > **프로젝트**: KRX 상장 한국 기업 대상 Equity Volatility → Default Rate by Rating > **작성일**: 2026-03-11 > **버전**: v0.1 (초안) --- ## 목차 1. [이론적 기초](#1-이론적-기초) 2. [핵심 수학적 프레임워크](#2-핵심-수학적-프레임워크) 3. [한국 시장 등급 관측 문제 및 대안](#3-한국-시장-등급-관측-문제-및-대안) 4. [글로벌 접근 방법론 비교](#4-글로벌-접근-방법론-비교) 5. [구현 아키텍처](#5-구현-아키텍처) 6. [데이터 명세](#6-데이터-명세) 7. [알고리즘 상세](#7-알고리즘-상세) 8. [검증 방법론](#8-검증-방법론) 9. [한국 시장 특수 고려사항](#9-한국-시장-특수-고려사항) 10. [기술 스택 및 의존성](#10-기술-스택-및-의존성) 11. [참고 문헌](#11-참고-문헌) --- ## 1. 이론적 기초 ### 1.1 구조적 모형(Structural Model) 계보 ``` Black-Scholes (1973) └─ Merton (1974) ─── 기업부도를 옵션으로 해석 ├─ Black-Cox (1976) ─── First Passage Time (배리어 부도) ├─ Geske (1977) ─── 복합옵션 (쿠폰부 부채) ├─ Longstaff-Schwartz (1995) ─── 확률적 이자율 └─ KMV (Kealhofer-McQuown-Vasicek) └─ Moody's Analytics EDF™ ─── 상용화 ``` ### 1.2 Merton 모형 (1974) **핵심 가정:** - 기업의 자산가치 `V(t)`는 기하 브라운 운동(GBM)을 따름 - 부채는 만기 `T`에 원금 `D`가 일시 상환되는 제로쿠폰 채권 - 자기자본 `E`는 자산 `V`에 대한 유럽형 콜옵션 **자산 역학:** ``` dV = μ·V·dt + σ_V·V·dW ``` - `μ`: 자산 기대수익률 (drift) - `σ_V`: 자산 변동성 - `W`: 위너 과정 **부도 조건:** ``` Default ⟺ V(T) < D (만기 시점에 자산가치 < 부채) ``` **자기자본의 옵션 해석:** ``` E = Call(V, D, T) = V·N(d₁) - D·e^{-rT}·N(d₂) ``` ### 1.3 KMV-Moody's EDF 모형 Merton 모형의 실무 확장: | 구분 | Merton 원형 | KMV 수정 | |------|-------------|----------| | 부도점 | D (총부채) | STD + 0.5×LTD | | 부도 시점 | 만기 T 시점만 | 임의 시점 (First Passage) | | EDF 산출 | N(-DD) 이론값 | 경험적 부도 빈도 매핑 | | 데이터 | 단일 시점 | 시계열 반복 추정 | ### 1.4 축약형 모형(Reduced-Form Model) **CreditRisk+ (Credit Suisse)** - 부도를 포아송 과정으로 모형화 - 부도율의 변동성을 명시적 반영 (부도율 자체가 확률변수) - 섹터별 체계적 요인으로 부도 상관관계 간접 포착 - 장점: 구현 용이, 대규모 포트폴리오 적합 - 한계: 시장 데이터 반영 제한, 등급전이 미반영 **Jarrow-Turnbull / Duffie-Singleton** - 부도 강도(hazard rate)가 시장 변수에 의존 - CDS/채권 스프레드에서 내재 부도확률 추출 - 한국 적용 한계: CDS 시장 유동성 부족 ### 1.5 CreditMetrics 접근법 - 등급전이행렬(Rating Transition Matrix) 기반 - 잠재 변수 `Zt`를 통해 체계적 리스크 반영 - 전이확률 × 등급별 스프레드 → 포트폴리오 가치 분포 - 한국 시장: 신평사 발표 전이행렬과 연동 가능 --- ## 2. 핵심 수학적 프레임워크 ### 2.1 Merton 연립방정식 관측 가능한 `(E, σ_E)`로부터 비관측 `(V, σ_V)`를 추정: **방정식 1 — 자기자본 가치:** ``` E = V·N(d₁) - D·e^{-rT}·N(d₂) ``` **방정식 2 — 변동성 관계 (Itô's Lemma):** ``` σ_E = (V/E)·N(d₁)·σ_V ``` **여기서:** ``` d₁ = [ln(V/D) + (r + σ²_V/2)·T] / (σ_V·√T) d₂ = d₁ - σ_V·√T ``` ### 2.2 Distance-to-Default (DD) ``` DD = [ln(V/DP) + (μ - σ²_V/2)·T] / (σ_V·√T) ``` - `DP = STD + 0.5 × LTD` (KMV 부도점) - `μ`: 자산 기대수익률 (실무에서는 r 또는 과거 추정값 사용) **해석:** DD는 자산가치가 부도점까지 하락하는 데 필요한 표준편차 수 ### 2.3 EDF 산출 **이론적 EDF (정규분포 가정):** ``` EDF_theoretical = N(-DD) = Φ(-DD) ``` **경험적 EDF (KMV 방식):** ``` EDF_empirical = (DD 구간별 실제 부도 기업 수) / (DD 구간별 전체 기업 수) ``` **한국 시장 보정 EDF:** ``` EDF_KR = EDF_theoretical × Calibration_Factor(rating_grade) ``` ### 2.4 주가 변동성 추정 방법 #### (a) 역사적 변동성 (Historical Volatility) ``` σ_E = √(252) × std(ln(P_t / P_{t-1})) ``` - 일별 로그수익률의 표준편차 × √252 (연환산) - 추정 윈도우: 1년 (약 250 거래일) #### (b) EWMA (Exponentially Weighted Moving Average) ``` σ²_t = λ·σ²_{t-1} + (1-λ)·r²_{t-1} ``` - `λ = 0.94` (RiskMetrics 표준) - 최근 변동에 더 높은 가중치 #### (c) GARCH(1,1) ``` σ²_t = ω + α·ε²_{t-1} + β·σ²_{t-1} ``` - `ω, α, β`: 최대우도추정(MLE)으로 산출 - `α + β < 1` (정상성 조건) - 변동성 클러스터링 반영 가능 --- ## 3. 한국 시장 등급 관측 문제 및 대안 ### 3.1 문제 진단 ``` KRX 상장사 약 2,500개 ├── 신용등급 보유: 약 500~600개 (주로 회사채/CP 발행사) │ ├── 관측 가능 등급: BBB ~ A 중심 (약 70%) │ ├── 고등급 (AAA~AA): 소수 (우량사, 등급 불필요) │ └── 저등급 (B 이하): 극소수 (상장 유지 자체가 어려움) └── 신용등급 미보유: 약 1,900개 (소형주, 미발행사) ``` **등급별 관측 분포 추정:** | 등급군 | KRX 상장사 중 비율 | 부도 관측 가능성 | 주요 이슈 | |--------|-------------------|-----------------|-----------| | AAA~AA | ~5% | 극히 낮음 | 부도 사례 거의 0 | | A | ~20% | 낮음 | 부도 희소하나 관측 가능 | | BBB | ~40% | 보통 | 가장 관측 풍부 | | BB | ~20% | 높음 | 투기등급 진입, 데이터 확보 | | B 이하 | ~5% | 높으나 표본 부족 | 상장폐지와 혼재 | | 무등급 | ~10% (등급보유 대비) | Shadow 필요 | 대부분 소형주 | ### 3.2 대안 전략 상세 #### 대안 1: Shadow Rating (내재등급) 모형 **목적:** DD 및 재무비율을 기반으로 무등급 기업에 내재등급 부여 **방법론 — Ordered Probit 모형:** ``` y* = β'X + ε, ε ~ N(0, 1) y = k if τ_{k-1} < y* ≤ τ_k 여기서: - y: 관측등급 (AAA=1, AA+=2, ..., D=n) - X: [DD, log(총자산), 부채비율, 이자보상비율, EBITDA마진, ROA, 유동비율, 산업더미] - τ_k: 등급 경계 절단점(cutoff) ``` **학습 과정:** 1. 등급 보유 기업의 (X, y) 쌍으로 β, τ를 MLE 추정 2. 등급 미보유 기업에 추정된 β'X를 적용하여 각 등급 확률 계산 3. 최대 확률 등급을 Shadow Rating으로 부여 **설명변수 후보:** | 변수 | 정의 | 기대 부호 | |------|------|-----------| | DD | Distance-to-Default | + (높을수록 고등급) | | log_assets | ln(총자산) | + 규모 효과 | | leverage | 총부채/총자산 | - | | int_coverage | EBITDA/이자비용 | + | | ebitda_margin | EBITDA/매출 | + | | roa | 순이익/총자산 | + | | current_ratio | 유동자산/유동부채 | + | | cash_ratio | 현금/유동부채 | + | | industry | 산업 더미 | 산업별 상이 | #### 대안 2: DD-Rating 직접 매핑 글로벌 벤치마크를 기반으로 DD 구간 → 등급 매핑: | DD 범위 | Moody's 등급 | 한국 등급 (추정) | 이론적 EDF | |---------|-------------|-----------------|------------| | > 6.0 | Aaa ~ Aa1 | AAA ~ AA+ | < 0.02% | | 5.0 ~ 6.0 | Aa2 ~ Aa3 | AA ~ AA- | 0.02% ~ 0.05% | | 4.0 ~ 5.0 | A1 ~ A3 | A+ ~ A- | 0.05% ~ 0.20% | | 3.0 ~ 4.0 | Baa1 ~ Baa2 | BBB+ ~ BBB | 0.20% ~ 0.70% | | 2.5 ~ 3.0 | Baa3 | BBB- | 0.70% ~ 1.50% | | 2.0 ~ 2.5 | Ba1 | BB+ | 1.50% ~ 3.00% | | 1.5 ~ 2.0 | Ba2 ~ Ba3 | BB ~ BB- | 3.00% ~ 5.00% | | 1.0 ~ 1.5 | B1 ~ B2 | B+ ~ B | 5.00% ~ 10.00% | | 0.5 ~ 1.0 | B3 ~ Caa1 | B- ~ CCC+ | 10.00% ~ 20.00% | | < 0.5 | Caa2 이하 | CCC 이하 | > 20.00% | > 주의: 글로벌 매핑은 한국 시장에 직접 적용 시 보정(calibration) 필수 #### 대안 3: 등급군 병합(Grade Pooling) 표본 부족 등급을 인접 등급과 통합: ``` Pool 1: AAA + AA+ + AA + AA- → "최우량군" (Super-Prime) Pool 2: A+ + A + A- → "우량군" (Prime) Pool 3: BBB+ + BBB + BBB- → "투자적격군" (Investment) Pool 4: BB+ + BB + BB- → "투기등급군" (Speculative) Pool 5: B+ 이하 → "고위험군" (High-Risk) ``` **병합 기준:** - 각 풀 내 최소 관측수: 30개 이상 (통계적 유의성) - Hosmer-Lemeshow 검정 등으로 풀 내 균질성 확인 #### 대안 4: 글로벌 데이터 블렌딩 한국 데이터와 글로벌 벤치마크를 표본수 기반 가중 혼합: ``` DR_blended(g) = w(g) × DR_KR(g) + [1 - w(g)] × DR_Global(g) w(g) = min(1, N_KR(g) / N_threshold) ``` - `DR_KR(g)`: 한국 등급 g의 관측 부도율 - `DR_Global(g)`: Moody's/S&P 등급 g의 글로벌 부도율 - `N_KR(g)`: 한국 등급 g의 관측 표본수 - `N_threshold`: 신뢰도 임계치 (예: 50) #### 대안 5: 베이지안 보정 ``` 사전분포(Prior): π(θ_g) ~ Beta(α_0, β_0) ← 글로벌 부도율에서 유도 우도(Likelihood): L(data|θ_g) = θ_g^d × (1-θ_g)^{n-d} 사후분포(Posterior): π(θ_g|data) ~ Beta(α_0 + d, β_0 + n - d) 여기서: - θ_g: 등급 g의 실제 부도율 (추정 대상) - d: 한국 등급 g에서 관측된 부도 건수 - n: 한국 등급 g에서 관측된 전체 기업수 - α_0, β_0: 글로벌 데이터에서 유도된 사전 파라미터 ``` **장점:** 표본 부족 등급에서 글로벌 Prior에 자연스럽게 의존, 표본 충분 등급에서는 한국 데이터 위주로 수렴 --- ## 4. 글로벌 접근 방법론 비교 | 방법론 | 모형 유형 | 핵심 입력 | 장점 | 한계 | 한국 적용성 | |--------|-----------|-----------|------|------|-------------| | **Merton-KMV** | 구조적 | 주가, 부채 | 시장기반, 전향적 | 상장사 한정, 분포가정 | ★★★★★ | | **CreditMetrics** | 전이행렬 | 등급전이, 스프레드 | 포트폴리오 리스크 | 등급 의존적 | ★★★☆☆ | | **CreditRisk+** | 축약형 | 부도율, 변동성 | 구현 용이 | 시장 미반영 | ★★☆☆☆ | | **Jarrow-Turnbull** | 축약형 | CDS스프레드 | 시장가격 반영 | CDS시장 미발달 | ★★☆☆☆ | | **Altman Z-Score** | 판별분석 | 재무비율 | 간단, 검증됨 | 시장변동 미반영 | ★★★☆☆ | | **ML (XGBoost)** | 비모수 | 다양한 데이터 | 유연, 비선형 | 해석부족, 과적합 | ★★★☆☆ | | **Bharath-Shumway** | 구조적(간편) | 주가, 부채 | 단순 구현 | 정밀도 한계 | ★★★★☆ | ### Bharath-Shumway 간편 DD (Naïve DD) 반복 추정 없이 직접 DD 계산 (실무 빠른 적용용): ``` V_naive = E + D σ_V_naive = (E/(E+D)) × σ_E + (D/(E+D)) × (0.05 + 0.25×σ_E) DD_naive = [ln(V_naive/D) + (μ - σ²_V_naive/2)×T] / (σ_V_naive × √T) ``` - Bharath & Shumway (2008) 연구에서 반복추정 DD와 유사한 부도예측력 보고 - 대규모 데이터 처리 시 1차 필터로 유용 --- ## 5. 구현 아키텍처 ### 5.1 시스템 구조 ``` EDF/ ├── config/ │ ├── settings.yaml # 전역 설정 (기간, 파라미터) │ └── rating_mapping.yaml # DD-등급 매핑 테이블 ├── data/ │ ├── raw/ # 원본 데이터 │ ├── processed/ # 전처리된 데이터 │ └── external/ # 글로벌 부도율 통계 ├── src/ │ ├── data/ │ │ ├── krx_fetcher.py # KRX 주가 수집 │ │ ├── dart_fetcher.py # DART 재무제표 수집 │ │ ├── rating_fetcher.py # 신용등급 수집 │ │ └── preprocessor.py # 데이터 전처리 │ ├── models/ │ │ ├── merton.py # Merton 연립방정식 풀이 │ │ ├── dd_calculator.py # DD/EDF 산출 │ │ ├── shadow_rating.py # Shadow Rating 모형 │ │ └── volatility.py # 변동성 추정 (Historical/EWMA/GARCH) │ ├── calibration/ │ │ ├── global_benchmark.py # 글로벌 벤치마크 로딩 │ │ ├── blending.py # 블렌딩/베이지안 보정 │ │ └── grade_pooling.py # 등급군 병합 │ ├── validation/ │ │ ├── backtesting.py # 백테스팅 │ │ ├── discriminatory.py # 변별력 검증 (ROC, KS, CAP) │ │ └── calibration_test.py # 보정력 검증 (Hosmer-Lemeshow) │ └── utils/ │ ├── financial.py # 재무비율 계산 │ └── statistics.py # 통계 유틸리티 ├── notebooks/ │ ├── 01_data_exploration.ipynb │ ├── 02_merton_analysis.ipynb │ ├── 03_shadow_rating.ipynb │ └── 04_default_rate_output.ipynb ├── outputs/ │ ├── dd_results/ # DD/EDF 산출 결과 │ ├── rating_results/ # 등급별 부도율 결과 │ └── reports/ # 검증 보고서 ├── docs/ │ └── technical_methodology.md # 이 문서 ├── requirements.txt └── README.md ``` ### 5.2 처리 파이프라인 ``` [Phase 1: 데이터 수집] KRX 주가 → 전처리 → 주가변동성 산출 DART 재무제표 → 부채 구조(STD/LTD) 추출 신평사 등급 → 연도별 등급 스냅샷 [Phase 2: Merton-KMV 모형] (E, σ_E, D, r, T) → 반복 추정 → (V, σ_V) → DP → DD → EDF [Phase 3: Shadow Rating] 등급 보유 기업: (DD, 재무비율) ↔ 등급 매핑 학습 등급 미보유 기업: 학습 모형 → Shadow Rating 부여 [Phase 4: 등급별 부도율 집계] 실제등급 + Shadow Rating → 등급별 연간 부도율 집계 표본 부족 등급 → 글로벌 블렌딩 / 등급군 병합 [Phase 5: 검증] 백테스팅, 변별력/보정력 검증, CRA 발표 데이터 비교 ``` --- ## 6. 데이터 명세 ### 6.1 필수 데이터 | 데이터 항목 | 소스 | 수집 주기 | 필수/선택 | |-------------|------|-----------|-----------| | 일별 종가 | KRX / pykrx | 일별 | 필수 | | 시가총액 | KRX / pykrx | 일별 | 필수 | | 발행주식수 | KRX / DART | 분기 | 필수 | | 유동부채 (STD) | DART 재무제표 | 분기/연간 | 필수 | | 비유동부채 (LTD) | DART 재무제표 | 분기/연간 | 필수 | | 총자산 | DART 재무제표 | 분기/연간 | 필수 | | 신용등급 | 한기평/한신평/나이스 | 연간 스냅샷 | 필수 | | 무위험이자율 | 한국은행(ECOS) | 일별 | 필수 | | 부도/워크아웃 이력 | KRX 상장폐지, 뉴스 | 사건 기반 | 필수 | ### 6.2 보조 데이터 (Shadow Rating 강화용) | 데이터 항목 | 소스 | 용도 | |-------------|------|------| | EBITDA | DART | 이자보상비율, 마진 | | 이자비용 | DART | 이자보상비율 | | 매출액 | DART | EBITDA 마진 | | 현금 및 현금성 자산 | DART | 유동성 비율 | | 산업분류코드 (KSIC) | KRX / DART | 산업 더미 변수 | | 거래량 | KRX | 유동성 필터링 | ### 6.3 글로벌 벤치마크 데이터 | 데이터 | 소스 | 내용 | |--------|------|------| | 등급별 연간 부도율 | Moody's Annual Default Study | Aaa~C 20년+ 평균 | | 등급별 누적 부도율 | S&P Global Default Study | AAA~D 1~20년 | | 한국 등급별 부도율 | 한기평/한신평/나이스 연간 발표 | 국내 기준 | ### 6.4 부도(Default) 정의 ``` 다음 이벤트 중 하나 이상 발생 시 "부도"로 정의: 1. 법정관리(회생절차) 개시 결정 2. 워크아웃(채권단 자율협약) 개시 3. 상장폐지 (재무 사유: 자본잠식, 감사의견 거절 등) 4. 부도어음/부도수표 발생 5. 기업회생절차 신청 6. 파산 선고 ※ 제외: 합병·분할·자진 상장폐지 등 비재무적 사유 ``` --- ## 7. 알고리즘 상세 ### 7.1 Merton 연립방정식 풀이 ```python import numpy as np from scipy.optimize import fsolve from scipy.stats import norm def solve_merton(E: float, sigma_E: float, D: float, r: float, T: float = 1.0) -> tuple[float, float]: """ Merton 연립방정식을 풀어 자산가치(V)와 자산변동성(σ_V)을 추정. Parameters ---------- E : float 자기자본 시장가치 (시가총액, 억원) sigma_E : float 주가수익률 변동성 (연환산, 예: 0.30 = 30%) D : float 부도점 = STD + 0.5 × LTD (억원) r : float 무위험이자율 (연, 예: 0.035 = 3.5%) T : float 시간 수평선 (년, 기본 1.0) Returns ------- V : float 추정 자산가치 (억원) sigma_V : float 추정 자산변동성 (연환산) """ def equations(params): V, sigma_V = params d1 = (np.log(V / D) + (r + 0.5 * sigma_V**2) * T) / (sigma_V * np.sqrt(T)) d2 = d1 - sigma_V * np.sqrt(T) eq1 = V * norm.cdf(d1) - D * np.exp(-r * T) * norm.cdf(d2) - E eq2 = (V / E) * norm.cdf(d1) * sigma_V - sigma_E return [eq1, eq2] # 초기값: V0 = E + D, sigma_V0 = sigma_E * E / (E + D) V0 = E + D sigma_V0 = sigma_E * E / (E + D) solution = fsolve(equations, [V0, sigma_V0], full_output=True) V, sigma_V = solution[0] return max(V, E), max(sigma_V, 0.01) # 하한 설정 def calculate_dd(V: float, sigma_V: float, D: float, mu: float, T: float = 1.0) -> float: """Distance-to-Default 산출""" if D <= 0 or V <= 0 or sigma_V <= 0: return np.nan DD = (np.log(V / D) + (mu - 0.5 * sigma_V**2) * T) / (sigma_V * np.sqrt(T)) return DD def calculate_edf(DD: float) -> float: """이론적 EDF 산출 (정규분포 가정)""" if np.isnan(DD): return np.nan return norm.cdf(-DD) ``` ### 7.2 변동성 추정 ```python def historical_volatility(prices: np.ndarray, window: int = 252) -> float: """역사적 변동성 (연환산)""" log_returns = np.diff(np.log(prices)) if len(log_returns) < window: window = len(log_returns) return np.std(log_returns[-window:]) * np.sqrt(252) def ewma_volatility(prices: np.ndarray, lmbda: float = 0.94) -> float: """EWMA 변동성 (연환산)""" log_returns = np.diff(np.log(prices)) variance = log_returns[0]**2 for ret in log_returns[1:]: variance = lmbda * variance + (1 - lmbda) * ret**2 return np.sqrt(variance * 252) def garch_volatility(prices: np.ndarray) -> float: """GARCH(1,1) 변동성 (arch 패키지 사용)""" from arch import arch_model log_returns = np.diff(np.log(prices)) * 100 # 백분율 model = arch_model(log_returns, vol='Garch', p=1, q=1, dist='normal') result = model.fit(disp='off') # 최신 조건부 변동성을 연환산 cond_vol = result.conditional_volatility[-1] / 100 return cond_vol * np.sqrt(252) ``` ### 7.3 Shadow Rating (Ordered Probit) ```python import statsmodels.api as sm import pandas as pd def fit_shadow_rating_model(df_rated: pd.DataFrame, feature_cols: list, rating_col: str = 'rating_numeric') -> object: """ 등급 보유 기업 데이터로 Ordered Probit 모형 적합. Parameters ---------- df_rated : pd.DataFrame 등급 보유 기업 데이터 (DD, 재무비율, 등급 포함) feature_cols : list 설명변수 컬럼명 리스트 rating_col : str 등급 숫자 컬럼 (1=AAA, 2=AA+, ...) """ X = df_rated[feature_cols] y = df_rated[rating_col] model = sm.OrderedModel(y, X, distr='probit') result = model.fit(method='bfgs', disp=False) return result def predict_shadow_rating(model_result, df_unrated: pd.DataFrame, feature_cols: list) -> pd.DataFrame: """등급 미보유 기업에 Shadow Rating 부여""" X = df_unrated[feature_cols] pred_probs = model_result.predict(X) # 각 기업의 최대 확률 등급 df_unrated = df_unrated.copy() df_unrated['shadow_rating_numeric'] = pred_probs.values.argmax(axis=1) + 1 return df_unrated ``` ### 7.4 등급별 부도율 산출 (블렌딩) ```python def compute_blended_default_rates(df: pd.DataFrame, rating_col: str, default_col: str, global_dr: dict, threshold: int = 50) -> pd.DataFrame: """ 등급별 부도율을 한국 관측 + 글로벌 벤치마크 블렌딩으로 산출. Parameters ---------- df : pd.DataFrame 전체 기업 데이터 (등급 + 부도여부 포함) rating_col : str 등급 컬럼명 default_col : str 부도 여부 컬럼명 (0/1) global_dr : dict {등급: 글로벌 부도율} 매핑 threshold : int 블렌딩 전환 표본수 임계치 """ results = [] for grade in sorted(df[rating_col].unique()): subset = df[df[rating_col] == grade] n = len(subset) d = subset[default_col].sum() kr_dr = d / n if n > 0 else 0 g_dr = global_dr.get(grade, kr_dr) w = min(1.0, n / threshold) blended = w * kr_dr + (1 - w) * g_dr results.append({ 'grade': grade, 'n_firms': n, 'n_defaults': d, 'korean_dr': kr_dr, 'global_dr': g_dr, 'weight_kr': w, 'blended_dr': blended }) return pd.DataFrame(results) ``` ### 7.5 베이지안 부도율 추정 ```python from scipy.stats import beta as beta_dist def bayesian_default_rate(n: int, d: int, prior_mean: float, prior_strength: float = 50) -> dict: """ 베이지안 방식 등급별 부도율 추정. Parameters ---------- n : int 관측 기업수 d : int 부도 건수 prior_mean : float 사전 부도율 (글로벌 벤치마크) prior_strength : float 사전 강도 (글로벌 표본수에 비례) """ # Beta prior 파라미터 alpha_0 = prior_mean * prior_strength beta_0 = (1 - prior_mean) * prior_strength # 사후 분포 (Beta-Binomial conjugacy) alpha_post = alpha_0 + d beta_post = beta_0 + (n - d) # 사후 통계량 posterior_mean = alpha_post / (alpha_post + beta_post) posterior_mode = (alpha_post - 1) / (alpha_post + beta_post - 2) \ if (alpha_post > 1 and beta_post > 1) else posterior_mean ci_lower, ci_upper = beta_dist.ppf([0.025, 0.975], alpha_post, beta_post) return { 'posterior_mean': posterior_mean, 'posterior_mode': posterior_mode, 'ci_95_lower': ci_lower, 'ci_95_upper': ci_upper, 'prior_mean': prior_mean, 'n_obs': n, 'n_defaults': d } ``` --- ## 8. 검증 방법론 ### 8.1 변별력(Discriminatory Power) 검증 | 지표 | 설명 | 기준 | |------|------|------| | **AUROC** | ROC 곡선 하 면적 | > 0.70 (수용), > 0.80 (양호) | | **KS 통계량** | 부도/비부도 분포 최대 이격 | > 0.30 (수용) | | **CAP/AR** | 정확도 비율 | > 0.50 (수용) | | **정보값(IV)** | 변수별 변별 기여도 | > 0.10 (유의미) | ### 8.2 보정력(Calibration) 검증 | 지표 | 설명 | |------|------| | **Hosmer-Lemeshow** | 예측 부도율 vs 실제 부도율 적합도 | | **Binomial Test** | 등급별 실제 부도율이 예측 구간 내 존재 여부 | | **Traffic Light** | Basel II 권장 — 녹색/황색/적색 신호 | ### 8.3 백테스팅 프로세스 ``` for year in [T-5, T-4, T-3, T-2, T-1]: 1. year 말 기준 DD/EDF 산출 2. year+1 동안의 실제 부도 여부 관측 3. 예측 EDF vs 실현 부도율 비교 4. 변별력/보정력 지표 산출 ``` ### 8.4 CRA 발표 데이터와 비교 - 한기평·한신평·나이스 연간 발표 등급별 부도율과 본 모형 산출치 비교 - 등급별 편차(bias) 및 상관관계 분석 - 부도 시점 대비 DD 하락 시점의 선행성 분석 --- ## 9. 한국 시장 특수 고려사항 ### 9.1 데이터 관련 | 항목 | 고려사항 | 대응 | |------|----------|------| | KOSPI vs KOSDAQ | KOSDAQ 소형·고변동성 기업 다수 | 시장별 분리 분석 또는 통합+더미 | | 금융업 | 부채 구조 상이 (예금 = 부채) | **분석 제외** 또는 별도 모형 | | 등급 불일치 | 한기평·한신평·나이스 등급 차이 | 중위값 또는 최빈값 사용 | | 분기 vs 연간 | 재무제표 시차 | 분기 데이터 우선, 없으면 연간 보간 | | 상장폐지 | 부도 vs 비부도 폐지 구분 | 폐지 사유 코드로 필터링 | ### 9.2 구조적 특성 | 특성 | 영향 | 모형 반영 방법 | |------|------|---------------| | **재벌 계열** | 그룹 지원으로 개별 DD 대비 부도율 하락 | 계열사 더미 / 그룹 DD 산출 | | **정부 지원** | 공기업 부도율 ≈ 0 | 정부지원 등급에서 제외 또는 별도 처리 | | **채권단 자율협약** | 형식적 부도 회피 | 워크아웃 개시를 부도 사건에 포함 | | **유상증자/CB** | 부도 직전 자본 확충으로 DD 왜곡 | 이벤트 전 DD 사용 또는 플래그 | ### 9.3 변동성 추정 주의사항 | 상황 | 문제 | 대응 | |------|------|------| | 장기 거래정지 | 변동성 과소추정 | 정지 기간 제외, 30일 이상 정지 시 분석 제외 | | 저거래량 | 비유동성 프리미엄 혼재 | 거래량 하위 10% 제외 또는 유동성 보정 | | 극단 이벤트 | 일시적 급등락으로 변동성 왜곡 | Winsorization (상하 1%) 또는 트리밍 | | 공매도 제한 | 하락 변동성 억제 | 변동성 하향 편의 인지, 글로벌 대비 보정 | --- ## 10. 기술 스택 및 의존성 ### 10.1 Python 패키지 ``` # 핵심 (requirements.txt) numpy>=1.24 pandas>=2.0 scipy>=1.10 statsmodels>=0.14 # 데이터 수집 pykrx>=1.0 # KRX 주가 데이터 OpenDartReader>=0.3 # DART 전자공시 API # 변동성 모형 arch>=6.0 # GARCH/EWMA 모형 # 시각화 matplotlib>=3.7 plotly>=5.15 seaborn>=0.12 # 머신러닝 (선택) scikit-learn>=1.3 xgboost>=2.0 # 유틸리티 tqdm>=4.65 pyyaml>=6.0 ``` ### 10.2 무위험이자율 - 한국은행 ECOS의 **국고채 1년물 금리** 사용 - 또는 통화안정증권(MSB) 1년물 ### 10.3 데이터베이스 - 개발 단계: SQLite (로컬 파일) - 운영 단계: PostgreSQL (필요시) --- ## 11. 참고 문헌 ### 핵심 논문 1. Merton, R.C. (1974). "On the Pricing of Corporate Debt: The Risk Structure of Interest Rates." *Journal of Finance*, 29(2), 449-470. 2. Black, F. & Cox, J.C. (1976). "Valuing Corporate Securities: Some Effects of Bond Indenture Provisions." *Journal of Finance*, 31(2), 351-367. 3. Bharath, S.T. & Shumway, T. (2008). "Forecasting Default with the Merton Distance to Default Model." *Review of Financial Studies*, 21(3), 1339-1369. 4. Crosbie, P. & Bohn, J. (2003). "Modeling Default Risk." Moody's KMV Working Paper. ### 한국 시장 연구 5. 한국은행. "IRB 접근법 하에서의 장기 부도확률 추정." 6. 한국기업평가. "연간 부도율 통계" (korearatings.com) 7. 한국신용평가. "신용등급별 부도율 및 전이행렬" (kisrating.com) ### 기술 참고 8. Credit Suisse Financial Products. (1997). "CreditRisk+: A Credit Risk Management Framework." 9. JP Morgan. (1997). "CreditMetrics — Technical Document." 10. Basel Committee on Banking Supervision. "Studies on the Validation of Internal Rating Systems."