stock-ai-agent/backend/app/models/signal.py
2026-02-24 22:05:30 +08:00

94 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
交易信号数据库模型
"""
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"<TradingSignal({self.signal_type} {self.symbol} {self.action} {self.grade} {self.confidence}%)>"
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
}