27 KiB
27 KiB
주식 변동성 기반 등급별 부도율 산출 — 기술 문서
프로젝트: KRX 상장 한국 기업 대상 Equity Volatility → Default Rate by Rating
작성일: 2026-03-11
버전: v0.1 (초안)
목차
- 이론적 기초
- 핵심 수학적 프레임워크
- 한국 시장 등급 관측 문제 및 대안
- 글로벌 접근 방법론 비교
- 구현 아키텍처
- 데이터 명세
- 알고리즘 상세
- 검증 방법론
- 한국 시장 특수 고려사항
- 기술 스택 및 의존성
- 참고 문헌
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)
학습 과정:
- 등급 보유 기업의 (X, y) 쌍으로 β, τ를 MLE 추정
- 등급 미보유 기업에 추정된 β'X를 적용하여 각 등급 확률 계산
- 최대 확률 등급을 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 |
| 한국 등급별 부도율 | 한기평/한신평/나이스 연간 발표 | 국내 기준 |
6.4 부도(Default) 정의
다음 이벤트 중 하나 이상 발생 시 "부도"로 정의:
1. 법정관리(회생절차) 개시 결정
2. 워크아웃(채권단 자율협약) 개시
3. 상장폐지 (재무 사유: 자본잠식, 감사의견 거절 등)
4. 부도어음/부도수표 발생
5. 기업회생절차 신청
6. 파산 선고
※ 제외: 합병·분할·자진 상장폐지 등 비재무적 사유
7. 알고리즘 상세
7.1 Merton 연립방정식 풀이
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 변동성 추정
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)
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 등급별 부도율 산출 (블렌딩)
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 베이지안 부도율 추정
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. 참고 문헌
핵심 논문
- Merton, R.C. (1974). "On the Pricing of Corporate Debt: The Risk Structure of Interest Rates." Journal of Finance, 29(2), 449-470.
- Black, F. & Cox, J.C. (1976). "Valuing Corporate Securities: Some Effects of Bond Indenture Provisions." Journal of Finance, 31(2), 351-367.
- Bharath, S.T. & Shumway, T. (2008). "Forecasting Default with the Merton Distance to Default Model." Review of Financial Studies, 21(3), 1339-1369.
- Crosbie, P. & Bohn, J. (2003). "Modeling Default Risk." Moody's KMV Working Paper.
한국 시장 연구
- 한국은행. "IRB 접근법 하에서의 장기 부도확률 추정."
- 한국기업평가. "연간 부도율 통계" (korearatings.com)
- 한국신용평가. "신용등급별 부도율 및 전이행렬" (kisrating.com)
기술 참고
- Credit Suisse Financial Products. (1997). "CreditRisk+: A Credit Risk Management Framework."
- JP Morgan. (1997). "CreditMetrics — Technical Document."
- Basel Committee on Banking Supervision. "Studies on the Validation of Internal Rating Systems."