feat(signal): M8.1 交易信号引擎(规则 + signal_event 落库 + /api/signals)
- SignalRules(买入 rank 阈值/趋势 MA/动量 + 卖出区间/破位警示)+ SignalEvent (BUY/WATCH/SELL,score/price/trigger_reason 可解释)+ SignalResult/Meta - quant/signal.generate_signals:与选股同一评分引擎取全市场 rank,按规则分类输出 - signal_snapshot/signal_event 表(migration d8e0b2f3c4d5,MySQL 已应用)+ Repo - SignalService + POST /api/signals(同步+落库)、GET 详情/列表 - tests/test_signals.py(引擎分类/排序/破位不 BUY、service、API 提交读回);全量 pytest 通过
This commit is contained in:
@@ -26,3 +26,7 @@ from app.infrastructure.persistence.sqlalchemy.models.selection import ( # noqa
|
||||
SelectionResultModel,
|
||||
SelectionSnapshotModel,
|
||||
)
|
||||
from app.infrastructure.persistence.sqlalchemy.models.signal import ( # noqa: F401
|
||||
SignalEventModel,
|
||||
SignalSnapshotModel,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
"""交易信号表(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)
|
||||
Reference in New Issue
Block a user