"""Market data API adapter - fetches quotes, bars, and reference data.""" import hashlib import logging from datetime import datetime from typing import Any, Dict import httpx from .base import AdapterResult, BaseAdapter logger = logging.getLogger("market_adapter") class MarketDataAdapter(BaseAdapter): """Concrete adapter for a market data provider (e.g., Alpha Vantage, Polygon, Yahoo).""" def __init__(self, api_key: str = "", base_url: str = ""): self.api_key = api_key self.base_url = base_url def source_type(self) -> str: return "market_api" async def fetch(self, ticker: str, config: Dict[str, Any]) -> AdapterResult: endpoint = config.get("endpoint", "/v2/aggs/ticker/{ticker}/prev") url = f"{self.base_url}{endpoint.format(ticker=ticker)}" params = config.get("params", {}) if self.api_key: params["apiKey"] = self.api_key async with httpx.AsyncClient(timeout=30) as client: try: resp = await client.get(url, params=params) resp.raise_for_status() raw = resp.content data = resp.json() content_hash = hashlib.sha256(raw).hexdigest() items = data.get("results", [data]) if isinstance(data, dict) else data return AdapterResult( source_type="market_api", ticker=ticker, items=items if isinstance(items, list) else [items], raw_payload=raw, content_hash=content_hash, fetched_at=datetime.utcnow(), ) except Exception as e: logger.error(f"Market fetch failed for {ticker}: {e}") return AdapterResult( source_type="market_api", ticker=ticker, items=[], raw_payload=b"", content_hash="", fetched_at=datetime.utcnow(), error=str(e), )