docs: known-issues 4건 추가 + devlog 2026-03-11 세션 기록
This commit is contained in:
@@ -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` 옵션으로 실행하지 말 것
|
||||
|
||||
6
docs/devlog/2026-03-11.md
Normal file
6
docs/devlog/2026-03-11.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Devlog — 2026-03-11
|
||||
|
||||
| # | 시간 | 작업 | 커밋 | 상태 |
|
||||
|---|------|------|------|------|
|
||||
| 001 | 19:21 | 프로젝트 초기 세팅 (.agents, 모듈, DB 스키마) | `a20a720` | ✅ |
|
||||
| 002 | 20:18 | KRX 2,609종목 주가/변동성 수집 + DART 2,497종목 재무제표 수집 | `e4b2c02` | ✅ |
|
||||
20
docs/devlog/entries/20260311-001.md
Normal file
20
docs/devlog/entries/20260311-001.md
Normal file
@@ -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금융 등 포함)
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user