""" 交易信号数据库模型 """ from datetime import datetime from sqlalchemy import Column, Integer, String, Text, DateTime, JSON, Float, Boolean from sqlalchemy.orm import relationship from app.models.database import Base class TradingSignal(Base): """交易信号表""" __tablename__ = "trading_signals" id = Column(Integer, primary_key=True, index=True) # 信号基本信息 signal_type = Column(String(20), nullable=False, index=True) # 'crypto' or 'stock' symbol = Column(String(50), nullable=False, index=True) # 交易对或股票代码 # 信号方向和评级 action = Column(String(10), nullable=False) # 'buy', 'sell', 'hold' grade = Column(String(5), nullable=False) # 'A', 'B', 'C', 'D' confidence = Column(Float, nullable=False) # 置信度 0-100 # 价格信息 entry_price = Column(Float, nullable=True) entry_zone = Column(Float, nullable=True) # 挂单价格 stop_loss = Column(Float, nullable=True) take_profit = Column(Float, nullable=True) current_price = Column(Float, nullable=True) # 信号生成时的当前价格 # 信号详情 signal_type_detail = Column(String(20), nullable=True) # 'short_term', 'medium_term', 'long_term' entry_type = Column(String(10), nullable=True) # 'market', 'limit' position_size = Column(String(20), nullable=True) # 'light', 'medium', 'heavy' # 分析信息 reason = Column(Text, nullable=True) # 信号理由 risk_warning = Column(Text, nullable=True) # 风险提示 analysis_summary = Column(Text, nullable=True) # 分析摘要 news_sentiment = Column(String(20), nullable=True) # 新闻情绪 news_impact = Column(String(100), nullable=True) # 消息影响 # 关键价位 key_levels = Column(JSON, nullable=True) # 支撑位和阻力位 # 技术指标(JSON 格式存储) indicators = Column(JSON, nullable=True) # 状态 is_active = Column(Boolean, default=True) # 信号是否有效 notified = Column(Boolean, default=False) # 是否已发送通知 notification_sent_at = Column(DateTime, nullable=True) # 时间戳 created_at = Column(DateTime, default=datetime.utcnow, index=True) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) def __repr__(self): return f"" def to_dict(self): """转换为字典""" return { 'id': self.id, 'signal_type': self.signal_type, 'symbol': self.symbol, 'action': self.action, 'grade': self.grade, 'confidence': self.confidence, 'entry_price': self.entry_price, 'entry_zone': self.entry_zone, 'stop_loss': self.stop_loss, 'take_profit': self.take_profit, 'current_price': self.current_price, 'signal_type_detail': self.signal_type_detail, 'entry_type': self.entry_type, 'position_size': self.position_size, 'reason': self.reason, 'risk_warning': self.risk_warning, 'analysis_summary': self.analysis_summary, 'news_sentiment': self.news_sentiment, 'news_impact': self.news_impact, 'key_levels': self.key_levels, 'indicators': self.indicators, 'is_active': self.is_active, 'notified': self.notified, 'notification_sent_at': self.notification_sent_at.isoformat() if self.notification_sent_at else None, 'created_at': self.created_at.isoformat() if self.created_at else None, 'updated_at': self.updated_at.isoformat() if self.updated_at else None, 'timestamp': self.created_at.isoformat() if self.created_at else None }