fix(etf): as_of_date에 가장 가까운 파일링 반환하도록 수정

- _load_snapshot_holdings(): DB 캐시 스냅샷이 as_of_date와 120일 초과
  차이나면 stale로 판단하고 None 반환 → SEC 신규 fetch 트리거
- _find_best_filing_and_xml(): eligible 필터에 365일 하한 추가,
  target_date 기준 1년 이내 파일링만 우선 후보로 사용
  (하한 내 후보 없으면 기존 전체 검색 fallback 유지)

수정 전: SPY?as_of_date=2021-06-30 → 2019-11-18 (19개월 stale)
수정 후: SPY?as_of_date=2021-06-30 → 2021-05-28 (정상)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
main
I Luk Kim 5 months ago
parent e75f1e1c72
commit d869ea98bd

@ -149,6 +149,13 @@ class ETFHoldingsFetcher:
snap = res.scalar_one_or_none()
if not snap:
return None
# 최대 허용 시차 검증: 120일 초과 시 stale로 판단 → SEC에서 새로 fetch
if as_of_date is not None:
gap = dt_norm - snap.snapshot_date
if gap.days > 120:
return None
hres = await db.execute(select(ETFHolding).where(ETFHolding.snapshot_id == snap.id))
rows = hres.scalars().all()
holdings = []
@ -268,6 +275,10 @@ class ETFHoldingsFetcher:
# Candidate list: newest first, filtered by date if provided.
# Ensure we include multiple prior days (not just the top day) to avoid missing the target series.
if target_date:
lower_bound = target_date - timedelta(days=365)
eligible = [(dt, acc) for dt, acc in filings if lower_bound <= dt <= target_date]
if not eligible:
# fallback: 하한 없이 전체 검색 (아주 오래된 ETF 등)
eligible = [(dt, acc) for dt, acc in filings if dt <= target_date]
if not eligible:
early_dt, early_acc = filings[0]

Loading…
Cancel
Save