Files
All-in-one-Financial-Analysis/atlas-terminal/server/core/data_gateway.py
T

146 lines
3.8 KiB
Python

"""Typed data gateway contract for market data access.
This module is intentionally provider-agnostic. Routers should eventually
depend on this Protocol instead of reaching into yfinance/FMP/yahooquery
directly.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from datetime import date, datetime
from typing import Any, Literal, Protocol
@dataclass(frozen=True)
class Quote:
symbol: str
price: float | None
currency: str | None = None
change: float | None = None
change_pct: float | None = None
market_time: datetime | None = None
source: str = ""
raw: dict[str, Any] = field(default_factory=dict)
@dataclass(frozen=True)
class Profile:
symbol: str
name: str | None = None
description: str | None = None
sector: str | None = None
industry: str | None = None
country: str | None = None
exchange: str | None = None
currency: str | None = None
website: str | None = None
employees: int | None = None
market_cap: float | None = None
source: str = ""
raw: dict[str, Any] = field(default_factory=dict)
@dataclass(frozen=True)
class Fundamentals:
symbol: str
period: str
name: str | None = None
market_cap: float | None = None
revenue: float | None = None
revenue_growth: float | None = None
gross_profit: float | None = None
gross_margin: float | None = None
operating_income: float | None = None
net_income: float | None = None
ebitda: float | None = None
free_cash_flow: float | None = None
total_assets: float | None = None
total_debt: float | None = None
cash: float | None = None
shares: float | None = None
pe: float | None = None
pb: float | None = None
ps: float | None = None
ev_ebitda: float | None = None
roic: float | None = None
source: str = ""
raw: dict[str, Any] = field(default_factory=dict)
@dataclass(frozen=True)
class OHLCVBar:
date: date
open: float | None
high: float | None
low: float | None
close: float | None
volume: float | None = None
@dataclass(frozen=True)
class OHLCV:
symbol: str
range: str
bars: list[OHLCVBar]
source: str = ""
@dataclass(frozen=True)
class Article:
title: str
url: str
source: str | None = None
published_at: datetime | None = None
summary: str | None = None
symbols: list[str] = field(default_factory=list)
@dataclass(frozen=True)
class Segment:
name: str
revenue: float | None = None
percent: float | None = None
period: str | None = None
@dataclass(frozen=True)
class HoldersData:
symbol: str
institutions: list[dict[str, Any]] = field(default_factory=list)
insiders: list[dict[str, Any]] = field(default_factory=list)
source: str = ""
@dataclass(frozen=True)
class EarningEvent:
symbol: str
event_date: date
fiscal_quarter: str | None = None
eps_estimate: float | None = None
revenue_estimate: float | None = None
status: Literal["confirmed", "estimated"] = "estimated"
source: str = ""
class DataGateway(Protocol):
async def quote(self, symbol: str) -> Quote: ...
async def profile(self, symbol: str) -> Profile: ...
async def fundamentals(self, symbol: str, period: str = "annual") -> Fundamentals: ...
async def financials(self, symbol: str, statement: str = "income", period: str = "annual") -> dict[str, Any]: ...
async def history(self, symbol: str, range: str = "1y") -> OHLCV: ...
async def news(self, symbols: list[str], limit: int = 20) -> list[Article]: ...
async def peers(self, symbol: str) -> list[str]: ...
async def segments(self, symbol: str) -> list[Segment]: ...
async def holders(self, symbol: str) -> HoldersData: ...
async def earnings_calendar(self, symbol: str) -> list[EarningEvent]: ...