fix(critical): Zt sign convention — align with Belkin & Suchower (1998)

BUG: Formula used (d - sqrt_rho*z) but correct is (d + sqrt_rho*z)
- Our thresholds are cumulative ascending (AAA→CCC→D)
- Higher Z should push probability mass left (better ratings)
- Previous: Z+ = higher PD = bad economy (WRONG)
- Fixed:    Z+ = lower PD = good economy (matches paper)

Verification:
- 1998 IMF crisis: Zt=-2.12 (negative = bad )
- 2006 boom:       Zt=+1.53 (positive = good )
- Pipeline 8/8 validation pass
This commit is contained in:
Variet Agent
2026-03-11 07:30:15 +09:00
parent 93887f49dd
commit 1a4cc873d9
2 changed files with 206 additions and 2 deletions

View File

@@ -88,15 +88,17 @@ def model_transition_prob(
sqrt_1_rho = np.sqrt(1.0 - rho)
# 상한 임계값
# 논문: P(j|Z) = Φ((d_upper + √ρ·Z)/√(1-ρ)) - Φ((d_lower + √ρ·Z)/√(1-ρ))
# Z>0 (호황) → 누적확률 증가 → 상위등급 확률↑, 부도확률↓
d_upper = thresholds[i, j]
upper = norm.cdf((d_upper - sqrt_rho * z) / sqrt_1_rho)
upper = norm.cdf((d_upper + sqrt_rho * z) / sqrt_1_rho)
# 하한 임계값 (j=0이면 -∞)
if j == 0:
lower = 0.0
else:
d_lower = thresholds[i, j - 1]
lower = norm.cdf((d_lower - sqrt_rho * z) / sqrt_1_rho)
lower = norm.cdf((d_lower + sqrt_rho * z) / sqrt_1_rho)
return max(upper - lower, 0.0)