feat: yfinance_plus .info 필드 지원 + company metadata 통합

- yfinance_plus submodule 업데이트 (EnhancedTicker.info property 추가)
- company_metadata_service: yfinance_plus 우선 import (fallback: vanilla yfinance)
- Dockerfile: COPY 후 site-packages에 로컬 yfinance_plus 덮어쓰기
- docs/DATA_COVERAGE.md: /company 엔드포인트 섹션 추가, /financial 변경사항 기록

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
main
I Luk Kim 4 months ago
parent 7f28266bd6
commit b322d28bd9

@ -11,12 +11,15 @@ RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*
COPY requirements-api.txt . COPY requirements-api.txt .
RUN pip install --no-cache-dir -r requirements-api.txt RUN pip install --no-cache-dir -r requirements-api.txt
# Install updated yfinance_plus from Gitea repository # Install updated yfinance_plus from Gitea repository (base version)
RUN pip install git+https://gitea.yirugi.synology.me/yirugi/yfinance_plus.git@9fae52e RUN pip install git+https://gitea.yirugi.synology.me/yirugi/yfinance_plus.git@9fae52e
# Copy application code # Copy application code
COPY . . COPY . .
# Override installed yfinance_plus with local version (adds .info property support)
RUN cp /app/yfinance_plus/yfinance_plus.py /usr/local/lib/python3.11/site-packages/yfinance_plus.py
# Create data directory for SQLite # Create data directory for SQLite
RUN mkdir -p /app/data RUN mkdir -p /app/data

@ -14,6 +14,9 @@ import logging
from datetime import datetime, timezone from datetime import datetime, timezone
from typing import Optional from typing import Optional
try:
import yfinance_plus as yf
except ImportError:
import yfinance as yf import yfinance as yf
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.dialects.postgresql import insert as pg_insert from sqlalchemy.dialects.postgresql import insert as pg_insert

@ -2,7 +2,7 @@
각 API 엔드포인트의 **실제 DB 보유 데이터 범위**와 **과거 데이터 백필 방법**을 정리한 문서입니다. 각 API 엔드포인트의 **실제 DB 보유 데이터 범위**와 **과거 데이터 백필 방법**을 정리한 문서입니다.
> 마지막 업데이트: 2026-03-29 > 마지막 업데이트: 2026-04-20
> DB 실측 기준 > DB 실측 기준
--- ---
@ -27,6 +27,8 @@
| `/insider/transactions` | SEC EDGAR Form 4 | ✅ | 요청 기반 자동 누적 | 2004년~ | 요청 기반 자동 누적 | | `/insider/transactions` | SEC EDGAR Form 4 | ✅ | 요청 기반 자동 누적 | 2004년~ | 요청 기반 자동 누적 |
| `/earnings/surprise` | yfinance-plus earnings_dates | ✅ | 요청 기반 자동 누적 | ~25분기 (6년+) | 요청 기반 자동 누적 | | `/earnings/surprise` | yfinance-plus earnings_dates | ✅ | 요청 기반 자동 누적 | ~25분기 (6년+) | 요청 기반 자동 누적 |
| `/universe/screen` | SEC EDGAR + yfinance 월별 스냅샷 | ✅ (사전 빌드 필요) | admin 빌드 후 사용 가능 | 2010년~ | **⚠️ 사전 빌드 필요** | | `/universe/screen` | SEC EDGAR + yfinance 월별 스냅샷 | ✅ (사전 빌드 필요) | admin 빌드 후 사용 가능 | 2010년~ | **⚠️ 사전 빌드 필요** |
| `/company/{ticker}` | yfinance-plus + universe_ticker_registry | ✅ (Redis 24h + DB 영구) | 모든 yfinance 지원 티커 | 즉시 | 요청 기반 자동 누적 |
| `/company/bulk` | yfinance-plus + universe_ticker_registry | ✅ (Redis 24h + DB 영구) | 최대 100 티커/요청 | 즉시 | 요청 기반 자동 누적 |
--- ---
@ -375,6 +377,62 @@ curl "http://localhost:18001/api/v1/universe/screen?date=2020-01-01&market_cap_m
--- ---
### `/api/v1/company` — 종목 메타데이터 (신규, 2026-04-20)
**현재 DB 보유**: 조회 시 자동 저장. 두 번째 조회부터 DB 히트 (Redis 24h → DB 영구).
**데이터 소스**: yfinance-plus `.info``universe_ticker_registry` + `companies` 테이블 UPSERT
**반환 필드**: `ticker`, `name`, `cik`, `exchange`, `sector`, `industry`, `country`, `market_cap`, `business_description`
| 엔드포인트 | 메서드 | 설명 |
|---|---|---|
| `/company/{ticker}` | `GET` | 단일 종목 메타데이터. 미지원 티커 → 404 |
| `/company/bulk` | `POST` | 최대 100개 일괄 조회. 부분 실패 허용 (per-ticker `error` 필드) |
**캐시 전략**:
- Redis 24h TTL (key: `company:meta:{TICKER}`)
- yfinance 실패 시 15분 TTL (재시도 빈도 조절)
- DB에 영구 저장 (sector 있는 경우 fast-path: DB만 조회, yfinance 미호출)
**조회 예시**:
```bash
# 단일 종목
curl "http://localhost:18001/api/v1/company/AU"
# → {"ticker":"AU","sector":"Basic Materials","industry":"Gold","exchange":"NYSE","country":"United States",...}
# 유효하지 않은 티커 → 404
curl "http://localhost:18001/api/v1/company/ZZZZZZ"
# → {"detail":"Unknown ticker: ZZZZZZ"}
# 최대 100개 일괄 조회
curl -X POST "http://localhost:18001/api/v1/company/bulk" \
-H "Content-Type: application/json" \
-d '{"tickers":["AU","USAS","CPRX","HE","ACHR"]}'
# → {"results":[...],"total":5,"success_count":5,"error_count":0}
```
**성능 특성**:
- 콜드 캐시 (첫 조회): yfinance 호출 ~2-5초 / 티커. 동시 최대 5개 (semaphore)
- 웜 캐시 (재조회): Redis <10ms / DB <50ms
- bulk 100개 콜드 캐시: ~30-50초 (semaphore=5로 직렬화)
**sector 대량 사전 보강** (선택):
```bash
# universe_ticker_registry의 NULL sector 전체 보강 (~30분, 9376 티커)
python scripts/backfill_registry_sector.py --batch 50
# Dry-run
python scripts/backfill_registry_sector.py --dry-run
```
**`/financial/data/{ticker}` 변경사항** (2026-04-20):
- `company` 블록에 `exchange`, `country`, `market_cap` 필드 추가
- placeholder sector(`Technology/Software/XXX Corporation`) 감지 시 자동 재보강
- financials/price 조회 실패 시에도 `company` 블록은 200 OK로 유지 (이전: 500 가능)
---
## 백필 우선순위 권장 사항 ## 백필 우선순위 권장 사항
| 우선순위 | 대상 | 이유 | 예상 소요 시간 | | 우선순위 | 대상 | 이유 | 예상 소요 시간 |

@ -1 +1 @@
Subproject commit 343aac090d06d6de7edca946be4f651112e43168 Subproject commit 674b7e45c8c79f3617dee9cffdd3f1438e4852cf
Loading…
Cancel
Save