ETF 분석툴 단계별 가이드: 미국·한국 ETF 분석부터 백테스트까지

ETF 분석 플랫폼 구축

Open optionsmarkdown

하려던 것 📝
- **미국 및 한국 ETF 분석 플랫폼(`etflab`) 구축**: 조건·목적 기반의 ETF 추천, 상태 트래킹, 과거 성과 백테스트를 제공하는 Python 라이브러리 및 CLI 개발.
- **무료 데이터 소스의 물리적 제약 극복**: 유료 API 없이 무료 데이터 소스(yfinance, Naver, FRED, NasdaqTrader)만을 활용하면서 발생하는 데이터 누락, 오차, 통동 차단 문제를 아키텍처 수준에서 해결.
- **강력한 데이터 정합성 가드 레일 장착**: 데이터의 룩어헤드 편향(Look-ahead bias) 및 이중 조정 오류를 방지하고 과거 시점의 철저한 재현성(Reproducibility) 확보.

활용한 툴 ⚒️
- **Claude Code**: 전체 `etflab` 아키텍처 설계, 다중 어댑터 계층 구현, SQLite+Parquet 하이브리드 캐시 개발, CheckedSeries/PointInTimeView 정합성 가드레일 설계.
- **Claude**: 일부 UI 명세 설계 및 도메인 제약사항(FRED, 네이버금융 등) 분석 지원.

진행 세부 내용 🔍
1️⃣ **도메인 정규화 및 무결성 가드레일 구축 (core & model)**
- `RunContext` 설계: 실행 시점 `as_of` 날짜를 모든 하위 함수 인자로 강제 전파하여 데이터 로드 단계에서 물리적 절단을 시행하고 과거 시점 재현성을 보장함.
- `units.py` 구축: TER 100배 오차(`netExpenseRatio` % vs `funds_data` 소수)와 금액/통화 혼용을 가드하기 위해 비율 해석 및 `Money(amount, currency)` 타입을 설계하여 단일 변환 경로로 통제함.
- `CheckedSeries` 보안 패턴: `IntegrityChecker.check()`를 통해서만 생성 가능하도록 private `_TOKEN`과 `InitVar` 매커니즘을 적용해 외부 직접 인스턴스화 및 `dataclasses.replace` 우회를 차단함.
- `PointInTimeView` 설계: 미래 데이터 유출(Look-ahead bias)을 방지하기 위해 `__slots__` 정의, `.copy()` 슬라이스 복사, 직렬화 거부 규칙을 갖춘 패널 절단 뷰를 구현함.

2️⃣ **다중 데이터 어댑터 연동 및 정규화 (adapters)**
- FRED 차단 우회: requests 18/18 타임아웃 차단 문제를 `curl_cffi` Chrome TLS impersonate 우회를 통해 해결하여 daily DTB3/DGS3MO 등의 무위험수익률을 정상적으로 확보함.
- 네이버금융 한국 특화 정규화: 네이버가 가격을 내리며 거래량을 올리는 특성`(ADJUSTED, ADJUSTED)`을 분석하여 `close_raw`를 의도적으로 `None` 처리해 이중 조정을 방지함.
- NAV 괴리율 계산 오차 해결: 네이버의 전일 NAV(`etfKeyIndicator`)와 당일 NAV(`totalInfos`) 혼용 시 20%p 괴리가 발생하는 것을 방지하기 위해 `NavFieldGroup` 태깅을 도입함.
- 상장폐지 오인 탐지: yfinance가 상폐 종목에 정상가 같은 고착가(FRAK 157.5)를 주는 문제를 해결하고자 최종 거래일 경과일수 검출 로직(`ListingStatus`)을 장착함.

3️⃣ **하이브리드 캐시 엔진 및 데이터 파이프라인 (cache)**
- SQLite + Parquet 하위 결합: 5,563종의 미국 ETF 수집 시 발생하는 약 32분의 수집 지연을 해소하기 위해, 가벼운 메타데이터 및 진실 인덱스는 SQLite(WAL 모드)로 관리하고, 대용량 시계열은 Parquet 파일로 저장하는 구조를 완성함.
- 원자적 캐시 갱신: 파일 오염 방지를 위해 임시 파일 작성 -> `fsync` -> `replace` 한 후 SQLite 인덱스를 커밋하는 원자적 트랜잭션을 적용함.

시행착오 ⚠️
- **KOSPI200 지수 결측 결함**: yfinance `^KS200` 지수의 2026-07-20~30 10거래일 누락 결함이 발견됨. 단순 `isna()`로 잡히지 않고 행 자체가 부재하는 현상이었으나, 캘린더 거래일 대조 로직(`TradingCalendar`)을 통해 `MISSING_ROWS` 경고를 달고 네이버 `KPI200`을 1차 소스로 삼아 해결함.
- **AUM 및 TER 소스 간 불일치**: yfinance의 `info.netAssets`와 `funds_data` 간 1.6~2.3배의 크기 불일치가 관측됨. 연속변수로 쓰면 리스크 계산이 불일치하므로 `AumBucket` 자릿수 구간으로 변환하여 매칭이 다를 때 보수적 구간 선택 및 불확실 플래그 처리함.
- **한국 팩터 시계열의 부재**: Ken French 라이브러리에 한국 팩터 파일이 없고, JKP Global Factor Data는 WRDS 구독이 필수적인 한계를 확인함. 결과적으로 한국 팩터 회귀 모델은 범위에서 제외하고, 수익률 기반 스타일 분석(M-29)으로 대안을 수립함.

배운 점 📚
- **Fail-Closed 설계의 중요성**: 무료 API는 조용한 실패(예외 없는 빈 결과 반환)가 빈번하므로 `@nonempty` 데코레이터를 통해 조기 발견하고, 정적 타입인 `CheckedSeries`로 무결성을 강제해야 계산 왜곡을 막을 수 있음을 체득함.
- **실측 기반 아키텍처 수립**: API 문서나 래퍼 라이브러리의 규격에 의존하지 않고, 실제 네트워크 지연과 차단(FRED requests 실패 등)을 프로브 스크립트로 직접 검증함으로써 신뢰할 수 있는 데이터 경로를 확정할 수 있었음.

향후 계획 🧭
- **일별 스냅샷 데몬 개발**: 과거 시점 유니버스 복원 불가능성(U7)과 일별 NAV 시계열 부재(U1, U2)를 해결하기 위해, 현재 시점부터 매일 수집하여 로컬 DB에 누적하는 스냅샷 자동 적재 시스템 개발.
- **핵심 연산 엔진(engine) 구현**: `CheckedSeries`와 `PointInTimeView`를 기반으로 Sharpe, MDD, Tracking Error, Amihud ILLIQ, 팩터 노출도 분석 및 포트폴리오 백테스터 구현.

도움이 필요한 점 🤝
1️⃣ **KRX 플러그인 연동 및 검증 지원**
- *현재 상황*: 거래소 차단 정책으로 인해 `KrxPluginAdapter`는 골격만 갖춘 채 비활성화되어 있으며, 자격증명(`KRX_ID`/`KRX_PW`) 설정 시의 실제 반환값 및 로그인 정합성을 검증할 방법이 없음.
- *필요한 도움*: 검증용 테스트 계정 또는 KRX 연동 데이터 스냅샷(JSON/CSV)을 확보하는 방안에 대한 가이드 지원이 필요함.

2️⃣ **한국 무위험수익률(Risk-Free) 데이터 획득 지원**
- *현재 상황*: FRED의 한국 3M CD 금리 시계열이 2023-12로 중단되었으며, 장기국채금리는 월별 빈도만 제공되어 일별 샤프지수 계산에 한계가 있음.
- *필요한 도움*: 한국은행 경제통계시스템(ECOS) API 연동 무료 인증키 획득 및 ECOS 일별 CD 금리 수집을 위한 가이드라인이 필요함.
3
1개의 답글
밀어주고 끌어주는

온·오프라인 AI 스터디

AI로 어디까지 할 수 있는지
직접 확인하실 분만 신청하세요.