- GET /price/data를 AlpacaPriceService 대신 PriceDataService(yfinance)로 교체
- ?ticker= alias 추가 (기존 ?tickers= 유지, 인터페이스 호환)
- _bulk_fetch_price_data: yfinance end 파라미터 exclusive 미반영 (+1일 누락) 수정
- get_multi_ticker_daily_bars: end_dt를 min.time(00:00) → max.time(23:59:59)으로 수정
(DB 쿼리 date <= end_dt 에서 당일 레코드가 필터링되던 버그)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
서비스 메서드가 db: AsyncSession을 인자로 받아 외부 API 호출(yfinance 30-60s,
Alpaca HTTP) 중에도 DB 커넥션을 잡고 있던 구조를 제거.
변경 패턴 (Session-per-phase):
Before: Endpoint(db) → Service(db) → DB check → API call(30s 세션 유지) → DB store
After: Endpoint() → Service() → DB check(세션1) → API call(세션 없음) → DB store(세션2)
변경 파일:
- alpaca_price_service.py: fetch_and_store_bars, get_or_fetch_multi_bars에서 db 제거
- price_data_service.py: get_or_update_price_data, get_multiple_tickers_data_optimized에서
db 제거; _fetch_price_data(새), _bulk_fetch_price_data(새, lambda 클로저 버그 수정);
_fetch_and_store_price_data, _bulk_fetch_and_store_price_data, get_multiple_tickers_data 제거
- alpaca.py, price.py: Depends(get_db) 제거 (GET /latest 제외)
- financial_service.py, real_sec_financial_service.py: 호출 인자 정리
결과: "idle in transaction" 커넥션 0개, 풀 고갈 원인 근본 해결
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Both GET /price/data and GET /alpaca/intraday:
- description에 배치 제한 설명 추가 (100개/요청, 자동 분할, 응답시간 선형 증가)
- 502 에러 메시지에 심볼 수 초과 가능성 힌트 추가
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
GET /price/intraday (Yahoo Finance):
- 15분 지연, 1m=7일/5m-30m=60일/1h=730일 한계
- 백테스트 용도, 실시간 전략 부적합
GET /alpaca/intraday (Alpaca IEX):
- 실시간, IEX 피드 2~5% 커버리지
- 거래량 낮게 표시, 가격 레벨은 유사
- ORB 등 당일 실시간 전략 용도
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Alpaca free plan blocks recent SIP data (403 on same-day requests).
Replace with Yahoo Finance which has no subscription requirement.
- PriceDataService.get_multi_intraday(): yf.download() in chunks of 50,
handles both single (flat DataFrame) and multi-ticker (MultiIndex) cases
- GET /price/intraday?tickers=...&interval=5m&start_date=...&end_date=...
→ same AlpacaMultiBarsResponse format (bars: {sym → [{timestamp,ohlcv}]})
→ source="YAHOO_FINANCE", Redis 5-min TTL cache
- /alpaca/intraday still exists for historical data (works on free plan)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- AlpacaPriceService.get_or_fetch_multi_bars(): checks DB max_date per
ticker, only fetches missing ranges from Alpaca, upserts with chunking
(3000 rows/chunk, asyncpg 32767-param limit) then reads back from DB
- GET /price/data endpoint: now uses service + Depends(get_db); subsequent
calls for same date range skip Alpaca entirely
- force_refresh=true bypasses DB check and re-fetches all from Alpaca
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>