48 lines
1.8 KiB
Python
48 lines
1.8 KiB
Python
"""SectorRotation model."""
|
|
|
|
from datetime import date, datetime
|
|
from decimal import Decimal
|
|
from typing import Any, Optional
|
|
|
|
from pydantic import BaseModel, ConfigDict
|
|
|
|
|
|
class SectorRotation(BaseModel):
|
|
"""Pydantic model for sector_rotations table."""
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: Optional[str] = None
|
|
detection_date: Optional[date] = None
|
|
sector_ticker: str
|
|
sector_name: Optional[str] = None
|
|
rank_now: Optional[int] = None
|
|
rank_previous: Optional[int] = None
|
|
rank_change: Optional[int] = None
|
|
momentum_20d: Optional[Decimal] = None
|
|
momentum_50d: Optional[Decimal] = None
|
|
momentum_200d: Optional[Decimal] = None
|
|
relative_strength: Optional[Decimal] = None
|
|
rotation_signal: Optional[str] = None
|
|
macro_context: Optional[dict] = None
|
|
analysis_summary: Optional[str] = None
|
|
created_at: Optional[datetime] = None
|
|
|
|
def to_dict(self) -> dict:
|
|
return {
|
|
"id": self.id,
|
|
"detectionDate": self.detection_date.isoformat() if self.detection_date else None,
|
|
"sectorTicker": self.sector_ticker,
|
|
"sectorName": self.sector_name,
|
|
"rankNow": self.rank_now,
|
|
"rankPrevious": self.rank_previous,
|
|
"rankChange": self.rank_change,
|
|
"momentum20d": float(self.momentum_20d) if self.momentum_20d else None,
|
|
"momentum50d": float(self.momentum_50d) if self.momentum_50d else None,
|
|
"momentum200d": float(self.momentum_200d) if self.momentum_200d else None,
|
|
"relativeStrength": float(self.relative_strength) if self.relative_strength else None,
|
|
"signal": self.rotation_signal,
|
|
"analysisSummary": self.analysis_summary,
|
|
"macroContext": self.macro_context,
|
|
}
|