""" GainerSnapshot — 5-min snapshots of Yahoo Finance day_gainers during market hours. Stored for backtesting: who was a top gainer at each intraday checkpoint. """ from datetime import datetime, timezone import uuid from sqlalchemy import Column, String, Float, Integer, BigInteger, Text, Index, UniqueConstraint from sqlalchemy.dialects.postgresql import UUID, TIMESTAMP from app.core.database import Base class GainerSnapshot(Base): __tablename__ = "gainer_snapshots" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) snapshot_at = Column(TIMESTAMP(timezone=True), nullable=False) rank = Column(Integer, nullable=False) symbol = Column(String(10), nullable=False) name = Column(Text, nullable=True) exchange = Column(String(20), nullable=True) price = Column(Float, nullable=True) change_percent = Column(Float, nullable=True) volume = Column(BigInteger, nullable=True) avg_volume_3m = Column(BigInteger, nullable=True) market_cap = Column(BigInteger, nullable=True) pe_ratio = Column(Float, nullable=True) forward_pe = Column(Float, nullable=True) eps_ttm = Column(Float, nullable=True) dividend_yield = Column(Float, nullable=True) fifty_two_week_high = Column(Float, nullable=True) fifty_two_week_low = Column(Float, nullable=True) created_at = Column( TIMESTAMP(timezone=True), default=lambda: datetime.now(timezone.utc) ) __table_args__ = ( # One symbol per snapshot timestamp (dedup on retry) UniqueConstraint("snapshot_at", "symbol", name="uq_gainer_snapshot_symbol"), Index("idx_gainer_snapshot_at", "snapshot_at"), Index("idx_gainer_symbol_snapshot", "symbol", "snapshot_at"), )