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.

17 KiB

Data Coverage & Backfill Guide

각 API 엔드포인트의 실제 DB 보유 데이터 범위과거 데이터 백필 방법을 정리한 문서입니다.

마지막 업데이트: 2026-03-29 DB 실측 기준


요약 테이블

엔드포인트 데이터 소스 DB 저장 현재 보유 범위 이론적 최대 범위 백필 필요
/price Yahoo Finance 2018-04-24 ~ 현재 (1682 티커) 20년+ 요청 기반 자동 누적
/alpaca/bars, /alpaca/data Alpaca API 테스트 데이터만 ~20년 필요시 수동
/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년~ ⚠️ 사전 빌드 필요

엔드포인트별 상세


/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에서 실시간 페치 → 자동 저장

백필: 별도 작업 불필요. 처음 조회 시 자동으로 인제스트됨.

# 특정 티커 과거 데이터 미리 채우기 (선택 사항)
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 보유: 테스트 데이터만 (AAPL 27일치). 실 운용 데이터 없음.

조회 파라미터:

  • start_date + end_date 필수
  • interval: 1m 5m 15m 1h 1d 1w 1mo

필수 조건: ALPACA_API_KEY, ALPACA_SECRET_KEY 환경 변수 설정 필요.

백필: /alpaca/data/{ticker} 엔드포인트 호출 시 자동으로 DB에 저장됨.

# Alpaca 과거 데이터 수동 백필
curl "http://localhost:18001/api/v1/alpaca/data/AAPL?start_date=2020-01-01&end_date=2024-12-31&interval=1d"

⚠️ /alpaca/bars는 DB에 저장되지 않음 (raw 조회 전용). DB 저장은 /alpaca/data만 해당.


/api/v1/finra — FINRA 공매도 (RegSHO)

현재 DB 보유: 2026-02-10 ~ 2026-03-20, 28거래일 (서비스 가동 시점부터)

데이터 소스인 FINRA CDN은 수년치 과거 파일을 보유하고 있으나, 현재 DB에는 최근 28일치만 있음.

조회 파라미터:

  • days: 최근 N일 (기본 30, 최대 365)
  • limit: 반환 최대 건수 (기본 100, 최대 1000)

⚠️ 백필 방법:

# 단일 날짜 백필
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 예시:

# 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 저장. 재조회 시 캐시.

# 특정 날짜 기준 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} 최초 호출 시 자동 인덱싱됨.

# 특정 티커 전체 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년부터 조회 가능.

# 파이프라인 수동 트리거 (신규 심볼 추가 시)
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 저장. 이후 캐시.

# 최근 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 캐시.

# 어닝 서프라이즈 이력 조회 (자동 인덱싱)
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)
# 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 — 등록된 종목 목록 조회

# 등록된 전체 종목 조회
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 — 종목 발견 및 등록

# $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 — 월별 시총 스냅샷 빌드

# 소규모 테스트 (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개 이상이면 백그라운드 실행.

초기 세팅 권장 순서

# 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"

백필 우선순위 권장 사항

우선순위 대상 이유 예상 소요 시간
🔴 높음 FINRA 1년치 (2025년) z-score 계산 윈도우(30일)가 너무 짧아 신호 품질 저하 20-40분
🔴 높음 Universe 스냅샷 빌드 백테스팅 유니버스 기능 사용 전 필수 1회 실행 30-60분 (4000 종목 × 10년)
🟡 중간 FINRA 2년치 (2024년) 더 긴 추세 분석 가능 1-2시간
🟢 낮음 Alpaca 데이터 Yahoo Finance와 중복, API 키 필요 필요시

FINRA 권장 백필 스크립트

# 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 상태 확인 쿼리

-- 각 테이블 데이터 범위 확인
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;