From 348b5bbf2700a049c3c4877d5e77a43eb908edd3 Mon Sep 17 00:00:00 2001 From: EDF Agent Date: Wed, 11 Mar 2026 23:25:55 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20known-issues=204=EA=B1=B4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20+=20devlog=202026-03-11=20=EC=84=B8=EC=85=98=20?= =?UTF-8?q?=EA=B8=B0=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .agents/references/known-issues.md | 24 +++++++++- docs/devlog/2026-03-11.md | 6 +++ docs/devlog/entries/20260311-001.md | 20 +++++++++ test_setup.py | 70 +++++++++++++---------------- 4 files changed, 79 insertions(+), 41 deletions(-) create mode 100644 docs/devlog/2026-03-11.md create mode 100644 docs/devlog/entries/20260311-001.md diff --git a/.agents/references/known-issues.md b/.agents/references/known-issues.md index 4eabd1a..5fbba7b 100644 --- a/.agents/references/known-issues.md +++ b/.agents/references/known-issues.md @@ -5,4 +5,26 @@ --- -(아직 기록된 이슈가 없습니다.) +### 2026-03-11 pykrx — get_market_ticker_list 항상 0 반환 +- **증상**: `stock.get_market_ticker_list(date, market="KOSPI")`가 모든 날짜에 0 반환 +- **원인**: pykrx 1.2.4 버전에서 ticker_list API가 정상 동작하지 않음 (2026년 환경) +- **해결**: DART `corp_codes`로 종목 목록 확보 + per-ticker `get_market_ohlcv`는 정상 동작 +- **주의**: `get_market_ticker_list` 의존하지 말 것. DART corp_codes를 종목 마스터로 사용 + +### 2026-03-11 pykrx — get_market_cap 단일일자 조회 시 시총=0 +- **증상**: `stock.get_market_cap(date, date, ticker)` 호출 시 시가총액이 0 반환 +- **원인**: 단일일자 조회 문법 이슈 (pykrx 내부 처리 문제) +- **해결**: `stock.get_market_cap_by_date(start, end, ticker)`로 15일 범위 조회 후 마지막 값 사용 +- **주의**: 단일일자 `get_market_cap` 사용 금지. 반드시 date range + `_by_date` 변형 사용 + +### 2026-03-11 DART — corp_codes 순서에 소형/비활성 종목 우선 +- **증상**: DART `corp_codes` 순서대로 수집 시 처음 10~20개가 전부 에러 (비활성/상폐 종목) +- **원인**: corp_codes 정렬이 코드 순이라 소형/비활성사가 앞에 위치 +- **해결**: KRX에서 주가 확인된 종목(volatility 테이블)만 DART 수집 대상으로 필터링 +- **주의**: DART 수집 시 반드시 KRX 활성 필터 적용. `finstate(stock_code, year)` 형태로 직접 조회 가능 + +### 2026-03-11 PowerShell — 인라인 Python f-string 이스케이핑 불가 +- **증상**: `python -c "...f'{var}'..."` 형태 인라인 코드가 PowerShell에서 파싱 오류 +- **원인**: PowerShell의 `'`, `"`, `{}` 이스케이핑이 Python f-string과 충돌 +- **해결**: 항상 별도 `.py` 파일로 작성하여 실행 +- **주의**: PowerShell에서 복잡한 Python 코드를 `-c` 옵션으로 실행하지 말 것 diff --git a/docs/devlog/2026-03-11.md b/docs/devlog/2026-03-11.md new file mode 100644 index 0000000..571c127 --- /dev/null +++ b/docs/devlog/2026-03-11.md @@ -0,0 +1,6 @@ +# Devlog — 2026-03-11 + +| # | 시간 | 작업 | 커밋 | 상태 | +|---|------|------|------|------| +| 001 | 19:21 | 프로젝트 초기 세팅 (.agents, 모듈, DB 스키마) | `a20a720` | ✅ | +| 002 | 20:18 | KRX 2,609종목 주가/변동성 수집 + DART 2,497종목 재무제표 수집 | `e4b2c02` | ✅ | diff --git a/docs/devlog/entries/20260311-001.md b/docs/devlog/entries/20260311-001.md new file mode 100644 index 0000000..ad7ea59 --- /dev/null +++ b/docs/devlog/entries/20260311-001.md @@ -0,0 +1,20 @@ +# EDF 프로젝트 초기 세팅 + 데이터 수집 + +- **시간**: 2026-03-11 19:21~23:18 +- **Commit**: `a20a720`, `e4b2c02` +- **Vikunja**: #312, #313, #317 → done + +## 결정 사항 + +1. **종목 목록 소스**: pykrx `get_market_ticker_list`가 동작하지 않아 DART `corp_codes`를 종목 마스터로 사용 +2. **시가총액 조회**: `get_market_cap_by_date` + 15일 범위 조회 (단일일자 조회는 0 반환) +3. **DART 필터링**: KRX에서 주가가 확인된(volatility 테이블 존재) 종목만 DART 수집 → 불필요한 API 호출 방지 +4. **DB 설계**: SQLite 8 테이블 (companies, market_data, financial_data, volatility, merton_results, credit_ratings, defaults, default_rates) +5. **기준일**: 2025-03-10 (pykrx가 2026년 데이터를 제공하지 않아 2025년 최근 거래일 사용) + +## 미완료 + +- #314 전체 종목 Merton DD/EDF 일괄 산출 → 다음 세션 +- #315 Shadow Rating 모델 구현 +- #316 등급별 부도율 산출 및 글로벌 블렌딩 +- 금융업 종목 필터링 미적용 (현재 KB금융 등 포함) diff --git a/test_setup.py b/test_setup.py index 1c393b4..5c5435c 100644 --- a/test_setup.py +++ b/test_setup.py @@ -1,44 +1,34 @@ -"""DART finstate test — stock code vs corp_code""" -import OpenDartReader -import time +"""DB stats and sample data""" +import sqlite3 -dart = OpenDartReader("ef6deb100be436aed88051fd4914dbdb58ff2e94") +conn = sqlite3.connect("data/edf.db") -# Test: finstate with stock code directly -print("=== DART finstate with stock code directly ===") -for code, name in [("005930", "삼성전자"), ("000660", "SK하이닉스"), ("036720", "한볼트")]: - try: - fs = dart.finstate(code, 2024) - time.sleep(0.5) - n = len(fs) if fs is not None else 0 - print(f" {code} {name}: {n} rows") - except Exception as e: - print(f" {code} {name}: ERROR {e}") +print("=== DB Stats ===") +for t in ["companies", "market_data", "financial_data", "volatility", "merton_results"]: + c = conn.execute(f"SELECT COUNT(*) FROM {t}").fetchone()[0] + print(f" {t}: {c:,}") -# Test: finstate_all — bulk download per corp_code -print("\n=== DART finstate_all (삼성전자 00126380) ===") -try: - fs = dart.finstate_all("00126380", 2024) - time.sleep(0.5) - n = len(fs) if fs is not None else 0 - print(f" 삼성전자 finstate_all: {n} rows") -except Exception as e: - print(f" ERROR: {e}") +print("\n=== Volatility sample ===") +rows = conn.execute("SELECT ticker, sigma_E FROM volatility ORDER BY ticker LIMIT 5").fetchall() +for r in rows: + print(f" {r[0]}: sigma_E={r[1]:.4f}") -# Test: KOSPI major — find their corp_codes and try finstate -print("\n=== DART finstate loop with known-good corp_codes ===") -corp_codes = dart.corp_codes -for ticker in ["005930", "000660", "005380", "036720", "040130"]: - match = corp_codes[corp_codes["stock_code"] == ticker] - if len(match) > 0: - cc = match.iloc[0]["corp_code"] - cn = match.iloc[0]["corp_name"] - try: - fs = dart.finstate(cc, 2024) - time.sleep(0.5) - n = len(fs) if fs is not None else 0 - print(f" {ticker} {cn} (corp={cc}): {n} rows") - except Exception as e: - print(f" {ticker} {cn}: ERROR {e}") - else: - print(f" {ticker}: Not found in corp_codes") +print("\n=== Financial sample ===") +rows = conn.execute(""" + SELECT ticker, total_assets, default_point, leverage_ratio + FROM financial_data WHERE total_assets IS NOT NULL + ORDER BY total_assets DESC LIMIT 5 +""").fetchall() +for r in rows: + dp = f"{r[2]:,.0f}" if r[2] else "N/A" + lev = f"{r[3]:.3f}" if r[3] else "N/A" + print(f" {r[0]}: TA={r[1]:,.0f} DP={dp} LEV={lev}") + +# Overlap: tickers with BOTH volatility AND financial_data +both = conn.execute(""" + SELECT COUNT(DISTINCT v.ticker) + FROM volatility v JOIN financial_data f ON v.ticker = f.ticker +""").fetchone()[0] +print(f"\n=== Merton 산출 가능 종목 (KRX+DART 모두 있는 종목): {both} ===") + +conn.close()