""" Stock and market data models. """ from datetime import datetime from sqlalchemy import ( Column, Integer, String, Numeric, DateTime, Date, BigInteger, Text, Enum as SQLEnum ) import enum from app.core.database import Base class StockType(str, enum.Enum): COMMON = "common" SPAC = "spac" PREFERRED = "preferred" REIT = "reit" OTHER = "other" class ReportType(str, enum.Enum): ANNUAL = "annual" QUARTERLY = "quarterly" class AssetClass(str, enum.Enum): EQUITY = "equity" BOND = "bond" GOLD = "gold" MIXED = "mixed" class Stock(Base): __tablename__ = "stocks" ticker = Column(String(20), primary_key=True) name = Column(String(100), nullable=False) market = Column(String(20), nullable=False) close_price = Column(Numeric(12, 2), nullable=True) market_cap = Column(BigInteger, nullable=True) eps = Column(Numeric(12, 2), nullable=True) forward_eps = Column(Numeric(12, 2), nullable=True) bps = Column(Numeric(12, 2), nullable=True) dividend_per_share = Column(Numeric(12, 2), nullable=True) stock_type = Column(SQLEnum(StockType), default=StockType.COMMON) base_date = Column(Date, nullable=False) class Sector(Base): __tablename__ = "sectors" ticker = Column(String(20), primary_key=True) sector_code = Column(String(10), nullable=False) company_name = Column(String(100), nullable=False) sector_name = Column(String(50), nullable=False) base_date = Column(Date, nullable=False) class Valuation(Base): __tablename__ = "valuations" ticker = Column(String(20), primary_key=True) base_date = Column(Date, primary_key=True) per = Column(Numeric(10, 2), nullable=True) pbr = Column(Numeric(10, 2), nullable=True) psr = Column(Numeric(10, 2), nullable=True) pcr = Column(Numeric(10, 2), nullable=True) dividend_yield = Column(Numeric(6, 2), nullable=True) class Price(Base): __tablename__ = "prices" ticker = Column(String(20), primary_key=True) date = Column(Date, primary_key=True) open = Column(Numeric(12, 2), nullable=False) high = Column(Numeric(12, 2), nullable=False) low = Column(Numeric(12, 2), nullable=False) close = Column(Numeric(12, 2), nullable=False) volume = Column(BigInteger, nullable=False) class Financial(Base): __tablename__ = "financials" ticker = Column(String(20), primary_key=True) base_date = Column(Date, primary_key=True) report_type = Column(SQLEnum(ReportType), primary_key=True) account = Column(String(50), primary_key=True) value = Column(Numeric(20, 2), nullable=True) class ETF(Base): __tablename__ = "etfs" ticker = Column(String(20), primary_key=True) name = Column(String(100), nullable=False) asset_class = Column(SQLEnum(AssetClass), nullable=False) market = Column(String(20), nullable=False) expense_ratio = Column(Numeric(5, 4), nullable=True) class ETFPrice(Base): __tablename__ = "etf_prices" ticker = Column(String(20), primary_key=True) date = Column(Date, primary_key=True) close = Column(Numeric(12, 2), nullable=False) nav = Column(Numeric(12, 2), nullable=True) volume = Column(BigInteger, nullable=True) class JobLog(Base): __tablename__ = "job_logs" id = Column(Integer, primary_key=True, index=True) job_name = Column(String(50), nullable=False) status = Column(String(20), nullable=False) started_at = Column(DateTime, default=datetime.utcnow) finished_at = Column(DateTime, nullable=True) records_count = Column(Integer, nullable=True) error_msg = Column(Text, nullable=True)