File size: 4,816 Bytes
65a8bf3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
from datetime import datetime
from sqlalchemy import (
    Column, Integer, String, Float, DateTime, Text, Boolean,
    ForeignKey, Index, UniqueConstraint
)
from sqlalchemy.orm import relationship
from .db import Base


class HistoricalPrice(Base):
    __tablename__ = "historical_prices"

    id = Column(Integer, primary_key=True, index=True)
    symbol = Column(String(10), nullable=False)
    timestamp = Column(DateTime, nullable=False)
    open = Column(Float, nullable=False)
    high = Column(Float, nullable=False)
    low = Column(Float, nullable=False)
    close = Column(Float, nullable=False)
    adjusted_close = Column(Float)
    volume = Column(Integer, default=0)
    dividend_amount = Column(Float, default=0.0)
    split_coefficient = Column(Float, default=1.0)
    ma20 = Column(Float)
    ma50 = Column(Float)
    rsi = Column(Float)
    created_at = Column(DateTime, default=datetime.utcnow)

    __table_args__ = (
        UniqueConstraint("symbol", "timestamp", name="uq_hist_symbol_ts"),
        Index("ix_hist_symbol", "symbol"),
        Index("ix_hist_timestamp", "timestamp"),
        Index("ix_hist_symbol_ts", "symbol", "timestamp"),
    )


class LiveMarketData(Base):
    __tablename__ = "live_market_data"

    id = Column(Integer, primary_key=True, index=True)
    symbol = Column(String(10), nullable=False)
    timestamp = Column(DateTime, nullable=False)
    open = Column(Float, nullable=False)
    high = Column(Float, nullable=False)
    low = Column(Float, nullable=False)
    close = Column(Float, nullable=False)
    volume = Column(Integer, default=0)
    vwap = Column(Float)
    created_at = Column(DateTime, default=datetime.utcnow)

    __table_args__ = (
        UniqueConstraint("symbol", "timestamp", name="uq_live_symbol_ts"),
        Index("ix_live_symbol", "symbol"),
        Index("ix_live_timestamp", "timestamp"),
        Index("ix_live_symbol_ts", "symbol", "timestamp"),
    )


class MarketNews(Base):
    __tablename__ = "market_news"

    id = Column(Integer, primary_key=True, index=True)
    news_id = Column(String(64), unique=True, nullable=False)
    headline = Column(Text, nullable=False)
    summary = Column(Text)
    source = Column(String(128))
    url = Column(Text)
    published_at = Column(DateTime, nullable=False)
    sentiment = Column(String(20))          # bullish | bearish | neutral
    confidence_score = Column(Float)         # 0.0 – 1.0
    overall_sentiment_score = Column(Float)
    importance_score = Column(Float, default=0.5)
    is_breaking = Column(Boolean, default=False)
    created_at = Column(DateTime, default=datetime.utcnow)

    topics = relationship("NewsTopic", back_populates="news", cascade="all, delete-orphan")
    ticker_sentiments = relationship("TickerSentiment", back_populates="news", cascade="all, delete-orphan")

    __table_args__ = (
        Index("ix_news_published_at", "published_at"),
        Index("ix_news_sentiment", "sentiment"),
        Index("ix_news_source", "source"),
    )


class NewsTopic(Base):
    __tablename__ = "news_topics"

    id = Column(Integer, primary_key=True, index=True)
    news_id_fk = Column(Integer, ForeignKey("market_news.id", ondelete="CASCADE"), nullable=False)
    topic = Column(String(128), nullable=False)
    relevance_score = Column(Float, default=0.0)

    news = relationship("MarketNews", back_populates="topics")

    __table_args__ = (
        Index("ix_topic_topic", "topic"),
        Index("ix_topic_news_id", "news_id_fk"),
    )


class TickerSentiment(Base):
    __tablename__ = "ticker_sentiment"

    id = Column(Integer, primary_key=True, index=True)
    news_id_fk = Column(Integer, ForeignKey("market_news.id", ondelete="CASCADE"), nullable=False)
    ticker = Column(String(10), nullable=False)
    relevance_score = Column(Float, default=0.0)
    sentiment_score = Column(Float, default=0.0)
    sentiment_label = Column(String(32))

    news = relationship("MarketNews", back_populates="ticker_sentiments")

    __table_args__ = (
        Index("ix_ts_ticker", "ticker"),
        Index("ix_ts_news_id", "news_id_fk"),
    )


class TechnicalIndicator(Base):
    __tablename__ = "technical_indicators"

    id = Column(Integer, primary_key=True, index=True)
    symbol = Column(String(10), nullable=False)
    timestamp = Column(DateTime, nullable=False)
    indicator_type = Column(String(32), nullable=False)   # SMA20, EMA50, RSI14, BB_UPPER, BB_LOWER, VWAP
    value = Column(Float, nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow)

    __table_args__ = (
        UniqueConstraint("symbol", "timestamp", "indicator_type", name="uq_ti_symbol_ts_type"),
        Index("ix_ti_symbol", "symbol"),
        Index("ix_ti_timestamp", "timestamp"),
        Index("ix_ti_ticker_ts", "symbol", "timestamp"),
    )