refactor: reconcile FundamentalsSnapshot to use canonical schema from trading.py

This commit is contained in:
Viktor Barzin 2026-02-23 21:45:18 +00:00
parent aa47e896dd
commit 6f512cf91f
No known key found for this signature in database
GPG key ID: 0EB088298288D958
6 changed files with 40 additions and 55 deletions

View file

@ -1,6 +1,6 @@
"""Fundamental data providers for stock financial metrics."""
from shared.fundamentals.base import FundamentalsProvider
from shared.fundamentals.base import FundamentalsProvider, FundamentalsSnapshot
from shared.fundamentals.rotating import RotatingProvider
__all__ = ["FundamentalsProvider", "RotatingProvider"]
__all__ = ["FundamentalsProvider", "FundamentalsSnapshot", "RotatingProvider"]

View file

@ -3,6 +3,7 @@
from __future__ import annotations
import logging
from datetime import datetime, timezone
import httpx
@ -63,13 +64,14 @@ class AlphaVantageProvider(FundamentalsProvider):
return FundamentalsSnapshot(
ticker=ticker,
eps=_safe_float(data.get("EPS")),
eps_ttm=_safe_float(data.get("EPS")),
pe_ratio=_safe_float(data.get("PERatio")),
peg_ratio=_safe_float(data.get("PEGRatio")),
revenue_growth=_safe_float(data.get("QuarterlyRevenueGrowthYOY")),
revenue_growth_yoy=_safe_float(data.get("QuarterlyRevenueGrowthYOY")),
profit_margin=_safe_float(data.get("ProfitMargin")),
debt_to_equity=_safe_float_div100(data.get("DebtToEquity")),
market_cap=_safe_float(data.get("MarketCapitalization")),
fetched_at=datetime.now(timezone.utc),
)
except Exception:
logger.exception("Alpha Vantage fetch failed for %s", ticker)

View file

@ -3,34 +3,12 @@
from __future__ import annotations
from abc import ABC, abstractmethod
from datetime import UTC, datetime
from pydantic import BaseModel, Field
from shared.schemas.trading import FundamentalsSnapshot # canonical definition
# ---------------------------------------------------------------------------
# FundamentalsSnapshot — canonical schema
#
# NOTE: This is the authoritative definition until it is moved into
# ``shared.schemas.trading``. Once the parallel schema task lands, delete
# this class and update all imports to point at the schemas module.
# ---------------------------------------------------------------------------
class FundamentalsSnapshot(BaseModel):
"""Point-in-time snapshot of a stock's fundamental financial metrics."""
ticker: str
eps: float | None = None
pe_ratio: float | None = None
peg_ratio: float | None = None
revenue_growth: float | None = None
profit_margin: float | None = None
debt_to_equity: float | None = None
market_cap: float | None = None
fetched_at: datetime = Field(default_factory=lambda: datetime.now(UTC))
model_config = {"from_attributes": True}
# Re-export so existing ``from shared.fundamentals.base import FundamentalsSnapshot``
# continues to work throughout the codebase.
__all__ = ["FundamentalsSnapshot", "FundamentalsProvider"]
# ---------------------------------------------------------------------------

View file

@ -3,6 +3,7 @@
from __future__ import annotations
import logging
from datetime import datetime, timezone
import httpx
@ -48,13 +49,14 @@ class FMPProvider(FundamentalsProvider):
return FundamentalsSnapshot(
ticker=ticker,
eps=_safe_float(item.get("netIncomePerShareTTM")),
eps_ttm=_safe_float(item.get("netIncomePerShareTTM")),
pe_ratio=_safe_float(item.get("peRatioTTM")),
peg_ratio=_safe_float(item.get("pegRatioTTM")),
revenue_growth=_safe_float(item.get("revenueGrowth")),
revenue_growth_yoy=_safe_float(item.get("revenueGrowth")),
profit_margin=_safe_float(item.get("netProfitMarginTTM")),
debt_to_equity=_safe_float(item.get("debtToEquityTTM")),
market_cap=_safe_float(item.get("marketCapTTM")),
fetched_at=datetime.now(timezone.utc),
)
except Exception:
logger.exception("FMP fetch failed for %s", ticker)

View file

@ -4,6 +4,7 @@ from __future__ import annotations
import asyncio
import logging
from datetime import datetime, timezone
from shared.fundamentals.base import FundamentalsProvider, FundamentalsSnapshot
@ -48,13 +49,14 @@ class YahooFinanceProvider(FundamentalsProvider):
return FundamentalsSnapshot(
ticker=ticker,
eps=_safe_float(info.get("trailingEps")),
eps_ttm=_safe_float(info.get("trailingEps")),
pe_ratio=_safe_float(info.get("trailingPE")),
peg_ratio=_safe_float(info.get("pegRatio")),
revenue_growth=_safe_float(info.get("revenueGrowth")),
revenue_growth_yoy=_safe_float(info.get("revenueGrowth")),
profit_margin=_safe_float(info.get("profitMargins")),
debt_to_equity=_safe_float_div100(info.get("debtToEquity")),
market_cap=_safe_float(info.get("marketCap")),
fetched_at=datetime.now(timezone.utc),
)
except Exception:
logger.exception("Yahoo Finance fetch failed for %s", ticker)