# Known Issues & Lessons Learned > **이 파일은 SSOT(Single Source of Truth)입니다.** > 디버깅이나 구현 전에 **반드시** 이 파일을 확인하세요. > 세션 종료 시 새로 발견된 이슈를 이 파일에 추가합니다. --- ## 포맷 각 항목은 아래 형식을 따릅니다: ```markdown ### [날짜] [키워드] — 한줄 요약 - **증상**: 무엇이 잘못되었는가 - **원인**: 근본 원인 - **해결**: 올바른 해결 방법 - **주의**: 재발 방지를 위한 교훈 ``` --- ## 공통 이슈 ### [2026-03-08] PowerShell curl — Invoke-WebRequest 충돌 - **증상**: `curl` 명령이 예상과 다른 응답 형식을 반환 - **원인**: PowerShell에서 `curl`은 `Invoke-WebRequest`의 별칭 - **해결**: **`curl.exe`**를 명시적으로 사용 - **주의**: HTTP 관련 모든 명령에서 `curl.exe` 사용 필수 ### [2026-03-08] PowerShell npm — 실행 정책 오류 - **증상**: `npm run` 명령이 `실행 정책` 관련 오류로 실패 - **원인**: PowerShell 스크립트 실행 정책이 제한적으로 설정됨 - **해결**: `cmd /c npm run dev` 형식으로 cmd를 통해 실행 - **주의**: npm 관련 명령은 항상 `cmd /c` 접두어 사용 권장 --- ## 프로젝트별 이슈 > 아래에 프로젝트 특화 이슈를 추가하세요. ### [2026-03-10] ECOS API 통계표코드 — 대부분 404 반환 - **증상**: `111Y002`, `817Y002`, `901Y067/A` 등 다수의 통계표코드/항목코드가 "해당하는 데이터가 없습니다" 반환 - **원인**: ECOS API 통계표 구조가 공식 문서와 다름. 예: GDP 성장률은 `111Y002`가 아닌 `902Y015` (국제 비교 통계), CD금리는 `817Y002`가 아닌 `721Y001` - **해결**: `StatisticItemList` API로 각 통계표의 항목코드를 조회한 후, `StatisticSearch`로 실제 데이터 반환 확인. 검증된 전체 코드 목록은 `config.yaml`에 기록됨 - **주의**: ECOS 통계표코드 변경 시 반드시 `StatisticItemList` → `StatisticSearch` 2단계 검증 수행. 선행지수(`901Y067`)는 연간 데이터 없음(월별만 존재) ### [2026-03-10] Windows CP949 인코딩 — Unicode 렌더링 실패 - **증상**: `matplotlib`에서 ✓, ✗, — (em dash) 등 Unicode 기호가 CP949에서 렌더링 실패 - **원인**: Windows 콘솔/Malgun Gothic 폰트가 해당 기호를 지원하지 않음 - **해결**: `sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')` + ASCII 대체 문자 사용 (Pass O / Fail X) - **주의**: 모든 Python 스크립트의 최상단에 UTF-8 stdout 설정 추가 필요 ### [2026-03-10] pandas fillna(method=) — Deprecation 오류 - **증상**: `fillna(method="ffill")` 호출 시 FutureWarning/Error - **원인**: pandas 2.x에서 `fillna(method=)` 인자 deprecated - **해결**: `df.ffill().bfill()` 메서드 체인으로 대체 - **주의**: pandas 2.x 이상 사용 시 `fillna(method=)` 전면 금지 ### [2026-03-11] Belkin Zt 부호 규칙 — 전체 파이프라인 부호 반전 버그 - **증상**: Zt 1998=+2.12 (IMF 위기인데 양수), 2006=-1.53 (호황인데 음수) - **원인**: Belkin 논문 원본: Z>0=호황(PD↓). 코드에서 임계값이 오름차순(AAA→D)인데 수식에 `(d - √ρ·Z)`로 구현하여 부호 반전. 올바른 수식은 `(d + √ρ·Z)` - **해결**: `credit_cycle.py`, `vasicek.py`, `transition_matrices.py` 3파일 모두 `(d - sqrt_rho * z)` → `(d + sqrt_rho * z)` 수정 - **주의**: vasicek.py의 `conditional_pd()`는 Basel convention (Z↑=불황)으로 별도 체계. 조건부 전이행렬은 Belkin convention (Z↑=호황). 두 규약이 코드에 공존하므로 반드시 docstring 확인 후 사용 ### [2026-03-11] ECOS 거시변수 — fallback 커버리지 부족 - **증상**: 기존 11개 변수만으로는 Zt 설명력 부족 (R² < 0.6) - **원인**: 한국 경제 특수성(유가의존, 수출주도, 부동산 영향 등) 미반영 - **해결**: 31개 변수로 확장 (KOSPI, OIL_PRICE, USDKRW, DISHONOR_RATE, HOUSING_PRICE, BSI_MANUF 등). `data/ecos_fetcher.py` + `data/cache/macro_ecos.csv` 캐싱 구조 - **주의**: fallback 데이터는 대략적 수치. 정밀 분석 시 ECOS API 실제 호출 필요 (`--force` 옵션) ### [2026-03-11] Windows Python — 소스 코드 특수문자 SyntaxError - **증상**: 파이썬 코드 내 문자열(예: docstring)에 `×` (U+00D7), `→` (U+2192) 등 특수문자나 한글 이외의 유니코드가 포함될 때, Windows CP949 환경에서 `SyntaxError: invalid character` 또는 `unterminated triple-quoted string literal` 로 파싱 오류가 발생함. - **원인**: Windows Python 3.12 런타임이 파일 맨 앞 `# -*- coding: utf-8 -*-` 이나 `-X utf8` 런타임 플래그도 소스 구문 분석 레벨에서 완벽하게 해석해내지 못하는 Windows 인코딩 고질병 문제 발생. - **해결**: 소스 코드 내에선 (특히 docstring 등 Python 인터프리터가 읽을 영역에서는) `×` 대신 `x` 또는 `by`를 사용하고, `→` 대신 `->` 로 ASCII 코드로 치환하여 작성함 (정규식 치환 등 활용). 한글 자체는 정상적으로 파싱됨. - **주의**: 모델링, 모듈 코드 작성 시 문자열이나 주석 내에 특수 유니코드 기호(×, →, —, §)를 직접 삽입하지 말고 안전한 ASCII 문자로 대체하여 코딩할 것. ### [2026-03-11] ADF 단위근 검정 — autolag='AIC' 소표본 과적합 - **증상**: Zt ADF 검정이 `autolag='AIC'`에서 p=0.40 (FAIL), `autolag='BIC'`에서 p=0.0000 (PASS) - **원인**: AIC는 소표본(N<50)에서 lag를 과다 선택 (N=26에서 lag=8 선택 -> 유효관측치=17 -> 검정력 상실). Hamilton (1994, Ch.17) 참조 - **해결**: `validation/statistical_tests.py`에서 `adfuller(series, autolag="AIC")` -> `adfuller(series, autolag="BIC")`, BIC는 보수적 lag 선택으로 소표본 적합 (Schwarz 1978) - **주의**: N<50 시계열 ADF 검정에서 항상 `autolag='BIC'` 사용. AIC는 대표본(N>100)에서만 신뢰할 것 ### [2026-03-11] KAP 채권 YTM PD Floor — 하드코딩 vs 실계산 혼동 - **증상**: `DEFAULT_PD_FLOORS` 하드코딩 값(BBB=20bp)과 KAP YTM 기반 실계산값(BBB=93bp)의 차이가 큼 - **원인**: `pd_floor.py`에 `build_complete_pd_floor_table()` 함수가 존재하나 사용되지 않고, `get_default_pd_floors()`만 호출 - **해결**: `main.py`와 `generate_report.py` 모두 `build_complete_pd_floor_table()` 호출로 변경. `ytm_fetcher.py` fallback 데이터(2025-12-31)로 오프라인에서도 작동 ### [2026-03-27] ECOS 월별 데이터 역산 시 연간 데이터와의 오차 - **증상**: KOSPI 평균이나 교역조건지수를 월별로 12분할 평균 낸 결과가 ECOS 연간 데이터(A) 고시와 소수점 이하 단위에서 완전 일치하지 않음. - **원인**: KOSPI 일평균의 영업일 가중치, 교역조건지수의 거래물량 가중치가 연간 산출 시 각 월의 편차를 발생시키기 때문. - **해결**: 대상이 통계 모형 입력 변수(거시 시나리오 모델링)라면 12개월 단순 평균의 오차율(약 0.05%)이 수치에 영향을 거의 미치지 않으므로, 복잡도 완화를 위해 단순 Aggregate를 허용하는 것으로 아키텍처 합의. (단, WTI 단순 평균, KOSPI 종가 등은 완벽 모사가 가능) - **주의**: 소수점 2째 자리 검증/심사표 등 완벽한 모사가 불가피할 경우, M/A 주기를 나눠 API를 2번씩 별도 Fetch해야 함.