You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

489 lines
20 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Data Coverage & Backfill Guide
각 API 엔드포인트의 **실제 DB 보유 데이터 범위**와 **과거 데이터 백필 방법**을 정리한 문서입니다.
> 마지막 업데이트: 2026-04-20
> DB 실측 기준
---
## 요약 테이블
| 엔드포인트 | 데이터 소스 | DB 저장 | 현재 보유 범위 | 이론적 최대 범위 | 백필 필요 |
|---|---|---|---|---|---|
| `/price` | Yahoo Finance | ✅ | 2018-04-24 ~ 현재 (1682 티커) | 20년+ | 요청 기반 자동 누적 |
| `/alpaca/intraday` (SIP, 과거) | Alpaca SIP | ✅ | 요청 기반 자동 누적 | 2016년~어제 | 요청 기반 자동 누적 |
| `/alpaca/intraday/today` (IEX, 당일) | Alpaca IEX | ✅ | 당일만 | 오늘 장 중 | 해당 없음 |
| `/alpaca/snapshot` | Alpaca IEX | ❌ | 실시간만 | 없음 | 해당 없음 |
| `/finra/short-volume` | FINRA CDN | ✅ | **2026-02-10 ~ 현재 (28거래일)** | 수년치 | **⚠️ 백필 권장** |
| `/etf/holdings` | SEC EDGAR (NPORT) | ✅ (스냅샷) | 요청 기반 자동 누적 | 2019년~ | 요청 기반 자동 누적 |
| `/filings/search` | SEC EDGAR | ✅ | 1994-01-05 ~ 현재 (1598 티커) | 1994년~ | 요청 기반 자동 누적 |
| `/stocks/most-active` | Yahoo 실시간 스크래핑 | ❌ | 실시간만 | 없음 | 해당 없음 |
| `/stocks/52-week-gainers` | Yahoo 실시간 스크래핑 | ❌ | 실시간만 | 없음 | 해당 없음 |
| `/stocks/trending` | Yahoo 실시간 스크래핑 | ❌ | 실시간만 | 없음 | 해당 없음 |
| `/overlay/{symbol}` | Yahoo/YouTube/Wikipedia/FINRA | ✅ | 2026-03-17 ~ 현재 (50 심볼) | 서비스 시작 이후 | 과거 백필 불가 |
| `/overlay/{symbol}/headlines` | Yahoo Finance RSS | ✅ | 2026-02-24 ~ 현재 | 서비스 시작 이후 | 과거 백필 불가 |
| `/overlay/{symbol}/wiki` | Wikipedia Pageviews API | ✅ | 2015-12-26 ~ 현재 | 2015년~ | 자동 수집됨 |
| `/insider/transactions` | SEC EDGAR Form 4 | ✅ | 요청 기반 자동 누적 | 2004년~ | 요청 기반 자동 누적 |
| `/earnings/surprise` | yfinance-plus earnings_dates | ✅ | 요청 기반 자동 누적 | ~25분기 (6년+) | 요청 기반 자동 누적 |
| `/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 티커/요청 | 즉시 | 요청 기반 자동 누적 |
---
## 엔드포인트별 상세
---
### `/api/v1/price` — 주가 (Yahoo Finance)
**현재 DB 보유**: 2018-04-24 ~ 현재, 1682 티커, 약 190만 행
**조회 파라미터**:
- `period`: `1d` `7d` `30d` `1m` `3m` `6m` `1y` `2y` `5y` `max`
- `start_date` + `end_date`: 특정 날짜 범위 (YYYY-MM-DD)
- `quarters`: `["2024Q1", "2024Q2"]` 형식
**동작 방식**: DB 캐시 우선 → 누락 구간만 Yahoo Finance에서 실시간 페치 → 자동 저장
**백필**: 별도 작업 불필요. 처음 조회 시 자동으로 인제스트됨.
```bash
# 특정 티커 과거 데이터 미리 채우기 (선택 사항)
curl -X POST "http://localhost:18001/api/v1/price/data" \
-H "Content-Type: application/json" \
-d '{"ticker": "AAPL", "start_date": "2020-01-01", "end_date": "2024-12-31"}'
```
---
### `/api/v1/alpaca` — 분봉 (Alpaca API)
**엔드포인트 구성**:
| 엔드포인트 | 피드 | 용도 | DB 저장 |
|---|---|---|---|
| `GET /alpaca/intraday` | **SIP** | 과거 분봉 (2016년~어제) | ✅ |
| `GET /alpaca/intraday/today` | **IEX** | 당일 실시간 분봉 | ✅ |
| `GET /alpaca/snapshot` | **IEX** | 현재가 스냅샷 | ❌ |
| `GET /alpaca/status` | — | API 키 유효성 확인 | ❌ |
**피드 차이**:
- **SIP**: 전체 미국 거래소 통합 데이터. 거래량 100% 정확. 과거 데이터(어제까지) 무료 접근.
- **IEX**: IEX 거래소 단일. 실시간이지만 거래량은 실제의 2~5%. 당일 데이터 전용.
**필수 조건**: `ALPACA_API_KEY`, `ALPACA_SECRET_KEY` 환경 변수 설정 필요.
**이론적 범위**: 2016년~ (Alpaca 무료 플랜 기준)
```bash
# 과거 5분봉 조회 (SIP, DB 저장)
curl "http://localhost:18001/api/v1/alpaca/intraday?tickers=AAPL,MSFT&interval=5m&start_date=2025-01-01&end_date=2025-01-31"
# 당일 실시간 분봉 (IEX)
curl "http://localhost:18001/api/v1/alpaca/intraday/today?tickers=AAPL,MSFT&interval=5m"
# 현재가 스냅샷
curl "http://localhost:18001/api/v1/alpaca/snapshot?tickers=AAPL,MSFT,SPY"
```
---
### `/api/v1/finra` — FINRA 공매도 (RegSHO)
**현재 DB 보유**: 2026-02-10 ~ 2026-03-20, 28거래일 (서비스 가동 시점부터)
> 데이터 소스인 FINRA CDN은 수년치 과거 파일을 보유하고 있으나, 현재 DB에는 최근 28일치만 있음.
**조회 파라미터**:
- `days`: 최근 N일 (기본 30, 최대 365)
- `limit`: 반환 최대 건수 (기본 100, 최대 1000)
**⚠️ 백필 방법**:
```bash
# 단일 날짜 백필
POST /api/v1/finra/admin/ingest?date=2025-01-02&force=false
# 날짜 범위 백필 (권장)
POST /api/v1/finra/admin/ingest?start_date=2024-01-01&end_date=2026-02-09&force=false
```
curl 예시:
```bash
# 2024년 전체 백필 (~252 거래일 × ~11,000 심볼 = ~280만 행)
curl -X POST "http://localhost:18001/api/v1/finra/admin/ingest?start_date=2024-01-01&end_date=2024-12-31"
# 2025년 전체 백필
curl -X POST "http://localhost:18001/api/v1/finra/admin/ingest?start_date=2025-01-01&end_date=2025-12-31"
# 운영 공백 구간 채우기 (2026-01-01 ~ 2026-02-09)
curl -X POST "http://localhost:18001/api/v1/finra/admin/ingest?start_date=2026-01-01&end_date=2026-02-09"
```
> 주의: 1년치 백필 시 ~3000 HTTP 요청 + DB write. 수십 분 소요될 수 있음. FINRA CDN은 API 키 없이 사용 가능하나 과부하를 피하기 위해 범위를 분할해서 실행 권장.
---
### `/api/v1/etf` — ETF 보유 종목 (SEC EDGAR)
**현재 DB 보유**: 요청된 ETF 스냅샷만 (요청 기반 자동 누적)
**이론적 범위**: 2019년~ (NPORT-P 도입 이후). 일부 ETF는 더 이전 N-Q 파일링 존재.
**조회 파라미터**:
- `as_of_date`: 기준 날짜 (YYYY-MM-DD). 가장 가까운 파일링 자동 선택.
- 생략 시: 가장 최신 파일링 반환.
**동작 방식**: 첫 조회 시 SEC EDGAR에서 자동 페치 → 스냅샷 DB 저장. 재조회 시 캐시.
```bash
# 특정 날짜 기준 ETF 보유 종목 조회 (자동 캐시)
curl "http://localhost:18001/api/v1/etf/holdings/QQQ?as_of_date=2023-12-31"
curl "http://localhost:18001/api/v1/etf/holdings/SPY?as_of_date=2022-06-30"
```
> ETF 출시 이전 날짜 요청 시 `availability` 필드에 가능한 날짜 범위 반환됨.
---
### `/api/v1/filings` — SEC 공시 (EDGAR)
**현재 DB 보유**: 1994-01-05 ~ 현재, 1598 티커, 약 8000일치
**지원 양식**: `8-K`, `6-K`, `20-F`, `40-F`
**조회 파라미터**:
- `form_type`: 쉼표 구분 (예: `8-K,6-K`)
- `start_date` + `end_date`: 공시 날짜 범위
- `limit` / `offset`: 페이지네이션 (최대 100)
**동작 방식**: 첫 조회 시 SEC EDGAR 자동 인덱싱 → DB 저장. 이후 DB 캐시. 1시간 Redis 캐시.
**백필**: 별도 작업 불필요. `GET /filings/search/{ticker}` 최초 호출 시 자동 인덱싱됨.
```bash
# 특정 티커 전체 8-K 조회 (자동 인덱싱)
curl "http://localhost:18001/api/v1/filings/search/AAPL?form_type=8-K&start_date=2020-01-01"
# 여러 티커 일괄 인덱싱
curl -X POST "http://localhost:18001/api/v1/filings/search/bulk" \
-H "Content-Type: application/json" \
-d '{"tickers": ["AAPL","MSFT","NVDA","TSLA"], "form_type": "8-K", "limit_per_ticker": 100}'
```
---
### `/api/v1/stocks` — 시장 현황 (Yahoo Finance 실시간)
**현재 DB 보유**: **없음**. 실시간 스크래핑 전용.
| 엔드포인트 | 데이터 | 캐시 TTL |
|---|---|---|
| `/stocks/most-active` | 실시간 상위 ~170 종목 | 1시간 |
| `/stocks/52-week-gainers` | 실시간 상위 ~1350 종목 | 1시간 |
| `/stocks/trending` | most-active + gainers 결합 | 30분 |
> 과거 데이터 조회 불가. 시계열 추적이 필요하면 주기적으로 `/price` 엔드포인트를 통해 개별 종목 가격을 저장하는 별도 배치 작업 필요.
---
### `/api/v1/overlay` — Attention Overlay
**현재 DB 보유**:
| 데이터 | 보유 범위 |
|---|---|
| Overlay score (feature records) | 2026-03-17 ~ 현재, 50 심볼 |
| 뉴스 헤드라인 | 2026-02-24 ~ 현재 |
| Wikipedia 페이지뷰 | 2015-12-26 ~ 현재 (풍부) |
| YouTube 멘션 | 서비스 시작 이후 |
| Google Trends | 서비스 시작 이후 |
**조회 파라미터**:
- `/{symbol}`: 최신 composite score
- `/{symbol}/history?days=N`: 스코어 시계열 (최대 365일)
- `/{symbol}/headlines?hours=N`: 뉴스 (최대 168시간)
- `/{symbol}/wiki?days=N`: Wikipedia 페이지뷰 (최대 90일)
- `/{symbol}/crowding`: FINRA 기반 crowding 지표
**지원 심볼**: 기본 50개 (`TOP_50_SYMBOLS`). 그 외 심볼은 파이프라인 트리거 필요.
**과거 데이터 백필**: Overlay score는 실시간 수집 기반으로 **과거 소급 생성 불가**.
Wikipedia 페이지뷰 (`/wiki`)는 2015년부터 조회 가능.
```bash
# 파이프라인 수동 트리거 (신규 심볼 추가 시)
POST /api/v1/overlay/admin/trigger-pipeline
# 특정 심볼의 헬스 상태 확인
GET /api/v1/overlay/admin/health
```
---
### `/api/v1/insider` — 내부자 거래 (SEC Form 4)
**현재 DB 보유**: 요청 기반 자동 누적 (첫 조회 시 자동 인덱싱)
**이론적 범위**: 2004년~ (EDGAR 전자 파일링 이후). 실제 커버리지는 기업마다 다름.
**조회 파라미터**:
- `GET /insider/transactions/{symbol}?days=90&transaction_type=P-Purchase`
- `GET /insider/summary/{symbol}?period=90d`: 집계 요약 (매수/매도 금액, 순매수)
**지원 거래 유형**: `P-Purchase`, `S-Sale`, `A-Award`, `D-Return`, `F-TaxWithholding`, `G-Gift`, `M-OptionExercise`
**동작 방식**: 첫 조회 시 SEC EDGAR Form 4 XML 자동 파싱 → DB 저장. 이후 캐시.
```bash
# 최근 90일 내부자 거래 조회 (자동 인덱싱)
curl "http://localhost:18001/api/v1/insider/transactions/NVDA?days=90"
# 내부자 매매 요약 (순매수/매도 금액)
curl "http://localhost:18001/api/v1/insider/summary/AAPL?period=90d"
```
---
### `/api/v1/earnings` — 어닝 서프라이즈 (yfinance-plus)
**현재 DB 보유**: 요청 기반 자동 누적 (첫 조회 시 자동 인덱싱)
**이론적 범위**: 약 25분기 (6년+). yfinance `earnings_dates` 데이터 기준.
**조회 파라미터**:
- `GET /earnings/surprise/{symbol}?limit=20`: 분기별 EPS surprise 이력
**반환 필드**: `reported_eps`, `estimated_eps`, `surprise`, `surprise_percentage`, `streak`
- `surprise` = reported_eps estimated_eps
- `surprise_percentage` = (surprise / estimated) × 100
- `streak`: 연속 beat(+) 또는 miss() 횟수
**동작 방식**: 첫 조회 시 yfinance `earnings_dates` 자동 인제스트 → DB 저장. 이후 1시간 Redis 캐시.
```bash
# 어닝 서프라이즈 이력 조회 (자동 인덱싱)
curl "http://localhost:18001/api/v1/earnings/surprise/AAPL?limit=20"
```
---
### `/api/v1/universe` — 과거 주식 유니버스 (백테스팅)
**현재 DB 보유**: admin 엔드포인트로 사전 빌드 필요 (초기에는 빈 상태)
**이론적 범위**: 2010년~ (SEC EDGAR 데이터 + yfinance 가격 데이터 가용 범위)
**데이터 소스**: SEC EDGAR `companyfacts` (shares_outstanding) × yfinance 월별 종가 → 월별 시총 계산
> **Survivorship bias 주의**: 현재 상장된 종목만 포함. 상폐 종목 미포함.
> **정확도**: 시총 오차 ±10~20% (buyback 반영 지연, SEC 분기별 업데이트 때문).
#### 워크플로우
```
1단계: 유니버스 등록 (1~5분)
POST /universe/admin/discover?market_cap_min=100000000
→ yfinance screener로 ~3000~5000 종목 발견
→ universe_ticker_registry 테이블에 저장
2단계: 스냅샷 빌드 (30~60분, 백그라운드)
POST /universe/admin/build-snapshots
→ SEC EDGAR shares_outstanding × yfinance 월별 종가 = 월별 시총
→ universe_snapshot 테이블에 ~480K 행 저장 (4000 × 120개월)
3단계: 과거 스크리닝
GET /universe/screen?date=2018-01-01&market_cap_min=2e9&market_cap_max=20e9
→ 2018년 초 기준 시총 $2B~$20B 종목 목록 반환
```
#### 엔드포인트 상세
**`GET /universe/screen`** — 과거 시점 기준 종목 스크리닝
| 파라미터 | 필수 | 설명 |
|---|---|---|
| `date` | ✅ | 기준 날짜 YYYY-MM-DD (월초로 자동 반올림) |
| `market_cap_min` | - | 최소 시총 (USD), 예: `2e9` = $2B |
| `market_cap_max` | - | 최대 시총 (USD), 예: `20e9` = $20B |
| `sector` | - | 섹터 필터 (예: `Technology`, `Healthcare`) |
| `exchange` | - | 거래소 필터 (`NYSE`, `NASDAQ`, `AMEX`) |
| `page` / `page_size` | - | 페이지네이션 (기본 100, 최대 500) |
| `sort_by` | - | 정렬 기준 (`market_cap` 또는 `ticker`) |
```bash
# 2018년 초 시총 $2B~$20B 종목 (Small/Mid Cap)
curl "http://localhost:18001/api/v1/universe/screen?date=2018-01-01&market_cap_min=2000000000&market_cap_max=20000000000"
# 2020년 기준 Technology 섹터 Large Cap ($10B+)
curl "http://localhost:18001/api/v1/universe/screen?date=2020-01-01&market_cap_min=10000000000&sector=Technology"
# 2023년 기준 Top 100 시총 순위
curl "http://localhost:18001/api/v1/universe/screen?date=2023-01-01&sort_by=market_cap&sort_ascending=false&page_size=100"
```
**`GET /universe/registry`** — 등록된 종목 목록 조회
```bash
# 등록된 전체 종목 조회
curl "http://localhost:18001/api/v1/universe/registry?page_size=200"
# NASDAQ 기술주 필터
curl "http://localhost:18001/api/v1/universe/registry?exchange=NASDAQ&sector=Technology"
```
**`POST /universe/admin/discover`** — 종목 발견 및 등록
```bash
# $100M 이상 ~3000~5000 종목 등록 (1~5분 소요)
curl -X POST "http://localhost:18001/api/v1/universe/admin/discover?market_cap_min=100000000"
# 소규모 테스트 ($1T 이상, ~50 종목)
curl -X POST "http://localhost:18001/api/v1/universe/admin/discover?market_cap_min=1000000000000"
```
**`POST /universe/admin/build-snapshots`** — 월별 시총 스냅샷 빌드
```bash
# 소규모 테스트 (3 종목 × 2년, 즉시 반환)
curl -X POST "http://localhost:18001/api/v1/universe/admin/build-snapshots" \
-H "Content-Type: application/json" \
-d '{"tickers":["AAPL","MSFT","NVDA"],"start_date":"2023-01-01","end_date":"2024-12-01"}'
# 전체 유니버스 × 10년 빌드 (백그라운드, 30~60분)
curl -X POST "http://localhost:18001/api/v1/universe/admin/build-snapshots" \
-H "Content-Type: application/json" \
-d '{"start_date":"2015-01-01","end_date":"2025-12-01","force_rebuild":false}'
```
> `tickers` 생략 시 registry 전체 대상. 20개 이하면 동기 실행(즉시 결과), 21개 이상이면 백그라운드 실행.
#### 초기 세팅 권장 순서
```bash
# 1. 유니버스 등록 ($100M+ → ~4000 종목)
curl -X POST "http://localhost:18001/api/v1/universe/admin/discover?market_cap_min=100000000"
# 2. 전체 스냅샷 빌드 (백그라운드 시작)
curl -X POST "http://localhost:18001/api/v1/universe/admin/build-snapshots" \
-H "Content-Type: application/json" \
-d '{"start_date":"2015-01-01","end_date":"2025-12-01"}'
# 3. 빌드 완료 후 스크리닝 테스트
curl "http://localhost:18001/api/v1/universe/screen?date=2020-01-01&market_cap_min=10000000000"
```
---
### `/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 가능)
---
## 백필 우선순위 권장 사항
| 우선순위 | 대상 | 이유 | 예상 소요 시간 |
|---|---|---|---|
| 🔴 높음 | FINRA 1년치 (2025년) | z-score 계산 윈도우(30일)가 너무 짧아 신호 품질 저하 | 20-40 |
| 🔴 높음 | Universe 스냅샷 빌드 | 백테스팅 유니버스 기능 사용 필수 1 실행 | 30-60 (4000 종목 × 10년) |
| 🟡 중간 | FINRA 2년치 (2024년) | 추세 분석 가능 | 1-2시간 |
| 🟢 낮음 | Alpaca 데이터 | Yahoo Finance 중복, API 필요 | 필요시 |
### FINRA 권장 백필 스크립트
```bash
# 1단계: 2025년 (가장 중요)
curl -X POST "http://localhost:18001/api/v1/finra/admin/ingest?start_date=2025-01-02&end_date=2025-12-31"
# 2단계: 2026년 공백 구간
curl -X POST "http://localhost:18001/api/v1/finra/admin/ingest?start_date=2026-01-02&end_date=2026-02-09"
# 3단계 (선택): 2024년
curl -X POST "http://localhost:18001/api/v1/finra/admin/ingest?start_date=2024-01-02&end_date=2024-12-31"
```
---
## 현재 DB 상태 확인 쿼리
```sql
-- 각 테이블 데이터 범위 확인
SELECT 'price_data' AS tbl, MIN(date)::date, MAX(date)::date, COUNT(DISTINCT date::date) AS days, COUNT(DISTINCT ticker) AS tickers FROM price_data
UNION ALL
SELECT 'finra_short_volume', MIN(date)::date, MAX(date)::date, COUNT(DISTINCT date::date), NULL FROM finra_short_volume
UNION ALL
SELECT 'sec_filings', MIN(filing_date)::date, MAX(filing_date)::date, COUNT(DISTINCT filing_date::date), COUNT(DISTINCT ticker) FROM sec_filings
UNION ALL
SELECT 'overlay_feature_records', MIN(as_of_ts)::date, MAX(as_of_ts)::date, COUNT(DISTINCT as_of_ts::date), COUNT(DISTINCT symbol) FROM overlay_feature_records
UNION ALL
SELECT 'insider_transactions', MIN(transaction_date)::date, MAX(transaction_date)::date, COUNT(DISTINCT transaction_date::date), COUNT(DISTINCT ticker) FROM insider_transactions
UNION ALL
SELECT 'earnings_surprise', MIN(earnings_date)::date, MAX(earnings_date)::date, COUNT(DISTINCT earnings_date::date), COUNT(DISTINCT ticker) FROM earnings_surprise
ORDER BY tbl;
-- Universe 스냅샷 상태 확인
SELECT
COUNT(DISTINCT ticker) AS tickers,
COUNT(*) AS snapshots,
MIN(snapshot_date)::date AS earliest,
MAX(snapshot_date)::date AS latest
FROM universe_snapshot;
-- Universe 등록 종목 수
SELECT COUNT(*) AS registered, COUNT(*) FILTER (WHERE is_active) AS active
FROM universe_ticker_registry;
```