93 lines
3.7 KiB
Python
93 lines
3.7 KiB
Python
"""
|
||
交易信号数据库模型
|
||
"""
|
||
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)
|
||
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
|
||
}
|