"""交易信号表(M8.1)。 signal_snapshot:一次信号运行的查询/规则/统计快照 signal_event:逐信号(signal_type + score/price + trigger_reason JSON) """ from __future__ import annotations from datetime import date, datetime from sqlalchemy import BigInteger, Date, DateTime, Integer, Numeric, String, Text from sqlalchemy.orm import Mapped, mapped_column from app.infrastructure.persistence.sqlalchemy.base import Base PK_INT = BigInteger().with_variant(Integer, "sqlite") class SignalSnapshotModel(Base): __tablename__ = "signal_snapshot" id: Mapped[str] = mapped_column(String(32), primary_key=True) as_of: Mapped[date] = mapped_column(Date, index=True) query_json: Mapped[str] = mapped_column(Text) rules_json: Mapped[str] = mapped_column(Text) statistics_json: Mapped[str] = mapped_column(Text) created_at: Mapped[datetime] = mapped_column(DateTime, index=True) class SignalEventModel(Base): __tablename__ = "signal_event" id: Mapped[int] = mapped_column(PK_INT, primary_key=True, autoincrement=True) signal_id: Mapped[str] = mapped_column(String(32), index=True) symbol: Mapped[str] = mapped_column(String(12)) signal_date: Mapped[date] = mapped_column(Date) signal_type: Mapped[str] = mapped_column(String(8)) score: Mapped[float | None] = mapped_column(Numeric(14, 6), nullable=True) price: Mapped[float | None] = mapped_column(Numeric(14, 4), nullable=True) reason_json: Mapped[str | None] = mapped_column(Text, nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime)