85 lines
2.2 KiB
Python
85 lines
2.2 KiB
Python
"""Provider protocols and lightweight data transfer objects.
|
|
|
|
Protocols define the interface for external data providers.
|
|
DTOs are simple dataclasses — NOT SQLAlchemy models — used to
|
|
transfer data between providers and the service layer.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from datetime import date, datetime
|
|
from typing import Protocol
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Data Transfer Objects
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class OHLCVData:
|
|
"""Lightweight OHLCV record returned by market data providers."""
|
|
|
|
ticker: str
|
|
date: date
|
|
open: float
|
|
high: float
|
|
low: float
|
|
close: float
|
|
volume: int
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class SentimentData:
|
|
"""Sentiment analysis result returned by sentiment providers."""
|
|
|
|
ticker: str
|
|
classification: str # "bullish" | "bearish" | "neutral"
|
|
confidence: int # 0-100
|
|
source: str
|
|
timestamp: datetime
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class FundamentalData:
|
|
"""Fundamental metrics returned by fundamental providers."""
|
|
|
|
ticker: str
|
|
pe_ratio: float | None
|
|
revenue_growth: float | None
|
|
earnings_surprise: float | None
|
|
market_cap: float | None
|
|
fetched_at: datetime
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Provider Protocols
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class MarketDataProvider(Protocol):
|
|
"""Protocol for OHLCV market data providers."""
|
|
|
|
async def fetch_ohlcv(
|
|
self, ticker: str, start_date: date, end_date: date
|
|
) -> list[OHLCVData]:
|
|
"""Fetch OHLCV data for a ticker in a date range."""
|
|
...
|
|
|
|
|
|
class SentimentProvider(Protocol):
|
|
"""Protocol for sentiment analysis providers."""
|
|
|
|
async def fetch_sentiment(self, ticker: str) -> SentimentData:
|
|
"""Fetch current sentiment analysis for a ticker."""
|
|
...
|
|
|
|
|
|
class FundamentalProvider(Protocol):
|
|
"""Protocol for fundamental data providers."""
|
|
|
|
async def fetch_fundamentals(self, ticker: str) -> FundamentalData:
|
|
"""Fetch fundamental data for a ticker."""
|
|
...
|