|
|
# Data Coverage & Backfill Guide
|
|
|
|
|
|
각 API 엔드포인트의 **실제 DB 보유 데이터 범위**와 **과거 데이터 백필 방법**을 정리한 문서입니다.
|
|
|
|
|
|
> 마지막 업데이트: 2026-04-26
|
|
|
> 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 | ✅ | **2018-08-01 ~ 현재 (1,829일, 22,722심볼)** | 2016년~ | 백필 완료 (2020-04~10 갭 제외) |
|
|
|
| `/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년~ | 요청 기반 자동 누적 |
|
|
|
| `/insider/form4/{ticker}` | SEC EDGAR Form 4 | ✅ | **최근 2년 (8개 quarter) 사전 bootstrap** | 2024년 Q3 ~ 현재, 676,858건 / 4,814 티커 | `bootstrap_form4_by_ticker.py` 완료 |
|
|
|
| `/insider/form4/by-date/{date}` | SEC EDGAR Form 4 | ✅ | 동상 | 동상 | 동상 |
|
|
|
| `/insider/form4/aggregate/{ticker}` | SEC EDGAR Form 4 | ✅ | 동상 | 동상 | 동상 |
|
|
|
| `/ownership/13dg/{ticker}` | SEC EDGAR SC 13D/G | ✅ | **최근 2년 (8개 quarter) 사전 bootstrap** | 2024년 Q3 ~ 현재, 42,329행 | `bootstrap_13dg.py` 완료 |
|
|
|
| `/ownership/13dg/active` | SEC EDGAR SC 13D/G | ✅ | 동상 | 동상 | 동상 |
|
|
|
| `/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 티커/요청 | 즉시 | 요청 기반 자동 누적 |
|
|
|
| `/news/v2/headlines` | Alpaca News (Benzinga) + StockTwits + Finnhub | ✅ (`news_headline`) | **ingest 시작 시점 이후만** (vendor 한계) | Alpaca: ingest 시작 누적 / Finnhub: 12개월 / StockTwits: 적재 시작 이후 | **⚠️ `NEWS_INGEST_ENABLED=true` opt-in 필요** |
|
|
|
| `/news/v2/session_aggregate*` | `news_headline` 즉시 SQL 집계 | ✅ (raw 기반) | headlines와 동일 | 동상 | 동상 |
|
|
|
| `/news/v2/coverage` | `news_headline` MIN/MAX/COUNT | — | — | — | 운영 도구 |
|
|
|
|
|
|
---
|
|
|
|
|
|
## 엔드포인트별 상세
|
|
|
|
|
|
---
|
|
|
|
|
|
### `/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 보유**: 2018-08-01 ~ 2026-05-29, **1,829 거래일, 22,722 심볼**
|
|
|
- FINRA CDN(무료, API 키 없음): `cdn.finra.org/equity/regsho/daily/CNMSshvol{YYYYMMDD}.txt`
|
|
|
- 롤링 ~7년 보유 (2018-08 이전 403)
|
|
|
- **2020-04-01 ~ 2020-10-31 결손** (~138 평일 — COVID 갭): `backfill_finra_2020_gap.py`로 메울 수 있음
|
|
|
|
|
|
#### PIT(Point-in-Time) 유니버스 멤버십
|
|
|
|
|
|
`finra_short_volume`에 등장한 22,722 심볼 중 **16,143개는 현 활성 유니버스(9,635)에 없는 상폐/합병 과거 종목**. DB의 `pit_universe_membership` 뷰로 노출.
|
|
|
|
|
|
```sql
|
|
|
-- 특정 날짜에 실제 거래되던 종목 (PIT 유니버스, 생존편향 0)
|
|
|
SELECT DISTINCT symbol FROM pit_universe_membership WHERE d = '2023-03-09';
|
|
|
-- SIVB, SBNY 등 그날 마지막으로 거래된 종목 포함됨
|
|
|
|
|
|
-- 공매도비율 횡단면 (상폐 종목 포함)
|
|
|
SELECT p.d, p.symbol, p.short_ratio, a.close
|
|
|
FROM pit_universe_membership p
|
|
|
LEFT JOIN alpaca_price_data a
|
|
|
ON a.ticker = p.symbol AND a.date::date = p.d AND a.interval = '1d'
|
|
|
WHERE p.d = '2023-03-09' ORDER BY p.short_ratio;
|
|
|
```
|
|
|
|
|
|
**⚠️ 한계**:
|
|
|
- **티커 재활용**: BBBY(2023-05 파산 → 2년 공백 → 2025-08 다른 엔티티)처럼 동일 티커가 재사용될 수 있음. 심볼 기준 PIT에서 경계 날짜 부근 ±2주 윈도우 제외 권장.
|
|
|
- **NMS 슈퍼셋**: ETF, ADR, 워런트(/U, /WS), 우선주 포함. 분석단에서 필터.
|
|
|
- 엄밀한 티커 재활용 해결 = CUSIP/PERMNO 매핑 (유료 데이터, 현재 범위 외).
|
|
|
|
|
|
#### API 조회 파라미터
|
|
|
|
|
|
- `days`: 최근 N일 (기본 30, **최대 3650 ≈ 10년**)
|
|
|
- `limit`: 반환 최대 건수 (기본 100, **최대 10000**)
|
|
|
- **주의**: `limit=100` 기본값은 "100 거래일"이 아니라 "100행" 제한. 전체 히스토리 조회 시 반드시 지정:
|
|
|
|
|
|
```bash
|
|
|
# SIVB 전체 히스토리 (상폐 전까지)
|
|
|
curl "http://localhost:18001/api/v1/finra/short-volume/SIVB?days=3650&limit=10000"
|
|
|
|
|
|
# 정규화된 일봉 공매도비율 (시장 통합)
|
|
|
curl "http://localhost:18001/api/v1/finra/short-ratio/AAPL?days=3650"
|
|
|
```
|
|
|
|
|
|
#### 2020 갭 메우기
|
|
|
|
|
|
```bash
|
|
|
docker exec stock_oracle_api python scripts/backfill_finra_2020_gap.py
|
|
|
# 예상 소요: ~10-20분, idempotent (이미 있는 날짜 자동 스킵)
|
|
|
```
|
|
|
|
|
|
> FINRA CDN은 API 키 없이 사용 가능. 1년치 백필 시 ~3000 HTTP 요청 + DB write, 20-40분 소요.
|
|
|
|
|
|
---
|
|
|
|
|
|
### `/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 보유**:
|
|
|
- **기존 `/transactions`, `/summary`**: 요청 기반 자동 누적 (첫 조회 시 자동 인덱싱)
|
|
|
- **신규 `/form4/*`**: 최근 2년 사전 bootstrap 완료 — 676,858건 / 4,814 티커 / 2024 Q3 ~ 2026-04-23
|
|
|
|
|
|
**자동 갱신**: 매 영업일 09:00 ET — 직전 영업일 daily full-index → Form 4 upsert (scheduler)
|
|
|
|
|
|
**⚠️ PIT 주의**: 신규 `/form4/*` 엔드포인트는 `as_of` 파라미터 **필수**. 누락 시 422.
|
|
|
|
|
|
---
|
|
|
|
|
|
#### 기존 엔드포인트 (Lazy on-demand)
|
|
|
|
|
|
```bash
|
|
|
# 최근 90일 내부자 거래 조회 (자동 인덱싱)
|
|
|
curl "http://localhost:18001/api/v1/insider/transactions/NVDA?days=90"
|
|
|
|
|
|
# 내부자 매매 요약 (순매수/매도 금액)
|
|
|
curl "http://localhost:18001/api/v1/insider/summary/AAPL?period=90d"
|
|
|
```
|
|
|
|
|
|
**지원 거래 유형**: `P-Purchase`, `S-Sale`, `A-Award`, `D-Return`, `F-TaxWithholding`, `G-Gift`, `M-OptionExercise`
|
|
|
|
|
|
---
|
|
|
|
|
|
#### 신규 PIT-safe 엔드포인트 (2026-04-23)
|
|
|
|
|
|
**`GET /insider/form4/{ticker}`** — 티커별 Form 4 거래 목록
|
|
|
|
|
|
| 파라미터 | 필수 | 설명 |
|
|
|
|---|---|---|
|
|
|
| `as_of` | ✅ | 기준 날짜 (YYYY-MM-DD). `filing_date <= as_of` 필터. |
|
|
|
| `start` | - | 시작 날짜 (filing_date 기준) |
|
|
|
| `end` | - | 종료 날짜 (filing_date 기준) |
|
|
|
| `buy_only` | - | `true` → 매수(`P`,`A`) 거래만 |
|
|
|
| `csuite_only` | - | `true` → CEO·CFO·COO·CTO 등 C-suite만 |
|
|
|
|
|
|
반환 필드: `symbol`, `filing_date`, `transaction_date`, `owner_cik`, `owner_name`, `owner_relationship`, `is_officer`, `is_director`, `is_ten_percent_owner`, `is_ceo`, `is_cfo`, `is_c_suite`, `shares`, `price`, `total_value`, `shares_owned_following`, `purchase_pct_of_holding`, `transaction_code`, `accession_number`
|
|
|
|
|
|
```bash
|
|
|
# TSLA CEO·CFO 매수 거래 조회
|
|
|
curl "http://localhost:18001/api/v1/insider/form4/TSLA?as_of=2026-04-20&start=2026-01-01&csuite_only=true&buy_only=true"
|
|
|
|
|
|
# NVDA 최근 30일 내부자 거래 전체
|
|
|
curl "http://localhost:18001/api/v1/insider/form4/NVDA?as_of=2026-04-20&start=2026-03-20"
|
|
|
```
|
|
|
|
|
|
**`GET /insider/form4/by-date/{date}`** — 특정 공시일 전체 거래 (cross-ticker)
|
|
|
|
|
|
| 파라미터 | 필수 | 설명 |
|
|
|
|---|---|---|
|
|
|
| `buy_only` | - | 매수 거래만 반환 |
|
|
|
|
|
|
```bash
|
|
|
# 2026-04-17 공시 전체 매수 거래
|
|
|
curl "http://localhost:18001/api/v1/insider/form4/by-date/2026-04-17?buy_only=true"
|
|
|
```
|
|
|
|
|
|
**`GET /insider/form4/aggregate/{ticker}`** — 집계 요약 (PIT-safe)
|
|
|
|
|
|
| 파라미터 | 필수 | 설명 |
|
|
|
|---|---|---|
|
|
|
| `as_of` | ✅ | 기준 날짜 |
|
|
|
| `window_days` | - | 집계 윈도우 (기본 30일). `filing_date ∈ (as_of - window_days, as_of]` |
|
|
|
|
|
|
반환 필드: `buy_count`, `buy_dollar_total`, `cluster_size`, `csuite_count`, `avg_pct_of_holding`, `recency_days`
|
|
|
|
|
|
```bash
|
|
|
# AAPL 최근 30일 내부자 매수 집계
|
|
|
curl "http://localhost:18001/api/v1/insider/form4/aggregate/AAPL?as_of=2026-04-20&window_days=30"
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
#### C-suite 판별 기준
|
|
|
|
|
|
`officer_title` 에 대해 case-insensitive 정규식 적용:
|
|
|
- `is_ceo`: `CEO`, `Chief Executive Officer`
|
|
|
- `is_cfo`: `CFO`, `Chief Financial Officer`, `Principal Financial Officer`
|
|
|
- `is_c_suite`: 위 둘 + `COO`, `CTO`, `CIO`, `CLO`, `CMO`, `President`, `Chairman/person/woman`, `Chief * Officer`
|
|
|
|
|
|
---
|
|
|
|
|
|
---
|
|
|
|
|
|
### `/api/v1/ownership` — Activist Ownership (SEC SC 13D/G) (신규, 2026-04-23)
|
|
|
|
|
|
**현재 DB 보유**: 42,329행, 최근 2년 (2024 Q3 ~ 2026-04-23) 사전 bootstrap 완료
|
|
|
|
|
|
**자동 갱신**:
|
|
|
- 매 영업일 09:00 ET — daily full-index → SC 13D/G index-only upsert
|
|
|
- 30분 주기 background enrich — `parse_status='index_only'` 200행씩 cover-page XML/HTML 파싱 → `ownership_pct`, `shares_owned` 보강
|
|
|
|
|
|
**parse_status 의미**:
|
|
|
- `index_only`: EDGAR 인덱스에서 가져온 기본 메타만 있음. `ownership_pct=NULL`
|
|
|
- `parsed`: cover-page XML/HTML 파싱 완료. `ownership_pct` 채워짐
|
|
|
- `parse_failed`: 파싱 시도했으나 문서 구조 불명확
|
|
|
|
|
|
**⚠️ PIT 주의**: `as_of` 파라미터 **필수**. 누락 시 422. 모든 날짜 필터는 `filing_date` 기준.
|
|
|
|
|
|
---
|
|
|
|
|
|
**`GET /ownership/13dg/{ticker}`** — 티커별 activist 이벤트 목록
|
|
|
|
|
|
| 파라미터 | 필수 | 설명 |
|
|
|
|---|---|---|
|
|
|
| `as_of` | ✅ | 기준 날짜. `filing_date <= as_of` 필터. |
|
|
|
| `start` | - | 시작 날짜 (filing_date 기준) |
|
|
|
| `end` | - | 종료 날짜 (filing_date 기준) |
|
|
|
|
|
|
반환 필드: `symbol`, `filing_date`, `filer_name`, `filer_cik`, `form_type`, `ownership_pct`, `shares_owned`, `is_amendment`, `change_pct`, `accession_number`, `parse_status`
|
|
|
|
|
|
`form_type` 값: `SC 13D`, `SC 13G`, `SC 13D/A`, `SC 13G/A` (또는 `SCHEDULE 13D/G` 등 변형 포함)
|
|
|
|
|
|
```bash
|
|
|
# AAPL activist filing 전체 (as_of 기준 이전)
|
|
|
curl "http://localhost:18001/api/v1/ownership/13dg/AAPL?as_of=2026-04-23"
|
|
|
|
|
|
# RLGT 2025년 이후 activist 이벤트
|
|
|
curl "http://localhost:18001/api/v1/ownership/13dg/RLGT?as_of=2026-04-23&start=2025-01-01"
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
**`GET /ownership/13dg/active`** — 현재 활성 activist 포지션 목록
|
|
|
|
|
|
| 파라미터 | 필수 | 설명 |
|
|
|
|---|---|---|
|
|
|
| `as_of` | ✅ | 기준 날짜 |
|
|
|
| `min_ownership_pct` | - | 최소 지분율 (기본 5.0) |
|
|
|
|
|
|
**쿼리 로직**: `(filer_cik, issuer_cik)` 쌍별 최신 filing (`filing_date DESC`) 한 행씩, `ownership_pct >= min_ownership_pct` 필터.
|
|
|
|
|
|
```bash
|
|
|
# 현재 5% 이상 activist 포지션 전체 (파싱된 행만)
|
|
|
curl "http://localhost:18001/api/v1/ownership/13dg/active?as_of=2026-04-23&min_ownership_pct=5.0"
|
|
|
|
|
|
# 10% 이상 대형 activist
|
|
|
curl "http://localhost:18001/api/v1/ownership/13dg/active?as_of=2026-04-23&min_ownership_pct=10.0"
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
#### Bootstrap (1회성, 이미 완료)
|
|
|
|
|
|
```bash
|
|
|
# 최근 8개 quarter SC 13D/G index-only 수집
|
|
|
docker exec stock_oracle_api python scripts/bootstrap_13dg.py --quarters 8
|
|
|
|
|
|
# Form 4 bootstrap (최근 2년)
|
|
|
docker exec stock_oracle_api python scripts/bootstrap_form4_by_ticker.py
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
### `/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§or=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§or=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 가능)
|
|
|
|
|
|
---
|
|
|
|
|
|
### `/api/v1/news/v2` — 멀티소스 헤드라인 + 세션 집계 (신규, 2026-04-26)
|
|
|
|
|
|
**현재 DB 보유**: `news_headline` 테이블. ingest 시작 후 누적. 빈 DB 상태에서도 엔드포인트는 200 + 빈 결과 반환.
|
|
|
|
|
|
**데이터 소스** (모두 `NEWS_INGEST_ENABLED=true` 시 활성화):
|
|
|
|
|
|
| Source | History | Rate limit | Sentiment |
|
|
|
|---|---|---|---|
|
|
|
| `alpaca_benzinga` | ~30일 vendor cap → ingest 시작 후 누적 | 200 req/min | 없음 (free tier) |
|
|
|
| `stocktwits` | rolling | 200 req/hr/IP | Bullish/Bearish → ±1 |
|
|
|
| `finnhub` | ~12개월 vendor cap | 60 calls/min free | 없음 |
|
|
|
|
|
|
**카테고리 정규화**: vendor 라벨 → 22-term 통합 vocab (`analyst_rating_*`, `earnings_release`, `m_and_a`, `fda_approval/rejection`, `buyback`, `litigation`, ... 등). 원본은 `vendor_categories`에 보존.
|
|
|
|
|
|
**세션 윈도우** (NYSE / `pandas_market_calendars` XNYS 휴장일·short day 처리):
|
|
|
- `premarket` = 전일 close → 당일 09:30 ET
|
|
|
- `intraday` = 09:30 → 16:00 ET
|
|
|
- `post` = 16:00 → 다음 거래일 04:00 ET (다음 premarket과 중복 없음)
|
|
|
- `full_session` = 전일 close → 다음 거래일 04:00 ET
|
|
|
|
|
|
**PIT 안전성**: 집계 시 `ingested_at <= window_end_utc` 필터 적용 → backtest가 lookahead 데이터를 못 봄.
|
|
|
|
|
|
| 엔드포인트 | 메서드 | 설명 |
|
|
|
|---|---|---|
|
|
|
| `/news/v2/headlines` | `GET` | raw 헤드라인 (symbols, start, end, sources, limit, cursor 필터) |
|
|
|
| `/news/v2/session_aggregate` | `GET` | 단일 ticker × session × window 집계 (Redis 캐시) |
|
|
|
| `/news/v2/session_aggregate/batch` | `POST` | 다수 ticker 일괄 (V49 핫패스, 캐싱 없음 — 클라이언트 disk-cache 가정) |
|
|
|
| `/news/v2/coverage` | `GET` | source × symbol 적재 깊이 probe |
|
|
|
|
|
|
**Ingest 활성화 절차**:
|
|
|
|
|
|
```bash
|
|
|
# 1. .env에 키 설정 (Alpaca는 기존 키 재사용, Finnhub은 신규)
|
|
|
echo "FINNHUB_API_KEY=<your-key>" >> .env
|
|
|
echo "NEWS_INGEST_ENABLED=true" >> .env
|
|
|
|
|
|
# 2. 컨테이너 재시작
|
|
|
docker restart stock_oracle_api
|
|
|
|
|
|
# 3. 로그에서 시작 메시지 확인
|
|
|
docker logs stock_oracle_api 2>&1 | grep "\[News\]"
|
|
|
# → "[News] ingest scheduler started — sources: ['alpaca_benzinga', 'finnhub', 'stocktwits']"
|
|
|
|
|
|
# 4. 5분 후 첫 Alpaca News poll 결과 확인
|
|
|
curl "http://localhost:18001/api/v1/news/v2/coverage?source=alpaca_benzinga"
|
|
|
```
|
|
|
|
|
|
**Fail-fast**: `NEWS_INGEST_ENABLED=true`인데 `ALPACA_API_KEY/SECRET` & `FINNHUB_API_KEY` 모두 없으면 scheduler 시작 거부 (StockTwits만으로는 신호 부족).
|
|
|
|
|
|
**Finnhub 12개월 백필** (수동 1회):
|
|
|
|
|
|
```bash
|
|
|
docker exec stock_oracle_api python scripts/news_backfill.py \
|
|
|
--source finnhub \
|
|
|
--tickers AAPL,MSFT,NVDA,TSLA,GOOGL \
|
|
|
--start 2025-04-26 --end 2026-04-26 \
|
|
|
--chunk monthly
|
|
|
# → 100 ticker × 12 month ≈ 1,200 calls @ 60 cpm ≈ 20분
|
|
|
```
|
|
|
|
|
|
**StockTwits 동적 universe** (자동, 매 평일 09:00 ET):
|
|
|
- `(최근 14일 V49 universe 합집합) ∪ (당일 09:00 ET premarket gap > threshold movers)`
|
|
|
- 기본 cap 300 ticker, 5분 polling, 200 req/hr 안정
|
|
|
- Config: `STOCKTWITS_UNIVERSE_LOOKBACK_DAYS` (14), `STOCKTWITS_PREMARKET_GAP_THRESHOLD` (0.02), `STOCKTWITS_UNIVERSE_MAX_SIZE` (300)
|
|
|
- Redis key: `news_v2:stocktwits:universe`
|
|
|
|
|
|
**제외**:
|
|
|
- WebSocket 실시간 push (P2)
|
|
|
- vendor 통합 sentiment NLP (현재는 vendor passthrough)
|
|
|
- GDELT raw feed 노출 (기존 attention 서브시스템 활용)
|
|
|
- Reddit/Twitter
|
|
|
|
|
|
---
|
|
|
|
|
|
## 백필 우선순위 권장 사항
|
|
|
|
|
|
| 우선순위 | 대상 | 이유 | 예상 소요 시간 |
|
|
|
|---|---|---|---|
|
|
|
| 🔴 높음 | **상폐 가격 백필** (PIT 생존편향-0) | 숏볼륨 신호 검정 시 수익 측 생존편향 제거 필수 | 1-3시간 |
|
|
|
| 🔴 높음 | **FINRA 2020 갭** (2020-04~10) | COVID 약세장/회복 레짐 없으면 멀티레짐 검정 불가 | 10-20분 |
|
|
|
| 🔴 높음 | Universe 스냅샷 빌드 | 백테스팅 유니버스 기능 사용 전 필수 1회 실행 | 30-60분 (4000 종목 × 10년) |
|
|
|
| 🟢 낮음 | 추가 FINRA 구간 | 이미 2018-08 ~ 현재 수집 완료 | — |
|
|
|
|
|
|
### 생존편향-0 데이터셋 구축 (권장 실행 순서)
|
|
|
|
|
|
```bash
|
|
|
# Step 1: FINRA 2020 갭 메우기 (10-20분, idempotent)
|
|
|
docker exec stock_oracle_api python scripts/backfill_finra_2020_gap.py
|
|
|
|
|
|
# Step 2: 상폐 가격 백필 — PIT 생존편향-0 핵심 (1-3시간, idempotent)
|
|
|
# FINRA 22,722 심볼 전체에 대해 Alpaca SIP 일봉 수집 (무료 플랜 포함)
|
|
|
# adjustment='all' (분할+배당 조정), 2018-08-01부터
|
|
|
docker exec stock_oracle_api python scripts/backfill_alpaca_daily_pit.py
|
|
|
|
|
|
# Step 3 (옵션): 리서치 레이어용 parquet export
|
|
|
# 외부 환경에서 직접 DB 연결 (port 15433) 후 pandas로 export:
|
|
|
# python -c "
|
|
|
# import pandas as pd
|
|
|
# from sqlalchemy import create_engine
|
|
|
# eng = create_engine('postgresql+psycopg2://stockoracle:stockoracle2024@localhost:15433/stock_oracle')
|
|
|
# df = pd.read_sql('SELECT p.d, p.symbol, p.short_ratio, a.close FROM pit_universe_membership p LEFT JOIN alpaca_price_data a ON a.ticker=p.symbol AND a.date::date=p.d AND a.interval=\'1d\' WHERE p.d BETWEEN \'2018-08-01\' AND NOW()', eng)
|
|
|
# df.to_parquet('pit_panel.parquet', index=False)
|
|
|
# print(df.shape)
|
|
|
# "
|
|
|
```
|
|
|
|
|
|
### PIT 뷰 (DB 직접 쿼리 시)
|
|
|
|
|
|
```sql
|
|
|
-- 날짜별 PIT 유니버스 (상폐 종목 포함)
|
|
|
SELECT DISTINCT symbol FROM pit_universe_membership WHERE d = '2023-03-09';
|
|
|
|
|
|
-- 공매도비율 × 가격 패널 (생존편향-0, backfill_alpaca_daily_pit.py 실행 후)
|
|
|
SELECT p.d, p.symbol, p.short_ratio, a.close
|
|
|
FROM pit_universe_membership p
|
|
|
LEFT JOIN alpaca_price_data a
|
|
|
ON a.ticker = p.symbol AND a.date::date = p.d AND a.interval = '1d'
|
|
|
WHERE p.d BETWEEN '2022-01-01' AND '2023-12-31'
|
|
|
ORDER BY p.d, p.short_ratio;
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
## 현재 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;
|
|
|
|
|
|
-- Form 4 PIT 데이터 상태
|
|
|
SELECT MIN(filing_date)::date, MAX(filing_date)::date, COUNT(*) AS txns, COUNT(DISTINCT ticker) AS tickers
|
|
|
FROM insider_transactions;
|
|
|
|
|
|
-- SC 13D/G activist 데이터 상태
|
|
|
SELECT parse_status, COUNT(*),
|
|
|
COUNT(*) FILTER (WHERE ownership_pct IS NOT NULL) AS has_pct,
|
|
|
MIN(filing_date)::date, MAX(filing_date)::date
|
|
|
FROM activist_ownership_events GROUP BY parse_status ORDER BY parse_status;
|
|
|
|
|
|
-- 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;
|
|
|
```
|