summaryrefslogtreecommitdiff
path: root/shared/src
diff options
context:
space:
mode:
authorTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-04-02 13:48:17 +0900
committerTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-04-02 13:48:17 +0900
commit24cd869302cfacad53ecd00cec0cef0a9393745b (patch)
tree9f6aea04c42dd5d738c3f34090ba95fb4503b6f6 /shared/src
parentb53867cb98691ef68d8e2c702e5bcd6c5f737744 (diff)
feat: add NewsItem, sentiment scoring, and stock selection models
Add NewsCategory enum and NewsItem model to shared/models.py. Create sentiment_models.py with SymbolScore, MarketSentiment, SelectedStock, Candidate.
Diffstat (limited to 'shared/src')
-rw-r--r--shared/src/shared/models.py23
-rw-r--r--shared/src/shared/sentiment_models.py44
2 files changed, 67 insertions, 0 deletions
diff --git a/shared/src/shared/models.py b/shared/src/shared/models.py
index 70820b5..a436c03 100644
--- a/shared/src/shared/models.py
+++ b/shared/src/shared/models.py
@@ -74,3 +74,26 @@ class Position(BaseModel):
@property
def unrealized_pnl(self) -> Decimal:
return self.quantity * (self.current_price - self.avg_entry_price)
+
+
+class NewsCategory(str, Enum):
+ POLICY = "policy"
+ EARNINGS = "earnings"
+ MACRO = "macro"
+ SOCIAL = "social"
+ FILING = "filing"
+ FED = "fed"
+
+
+class NewsItem(BaseModel):
+ id: str = Field(default_factory=lambda: str(uuid.uuid4()))
+ source: str
+ headline: str
+ summary: Optional[str] = None
+ url: Optional[str] = None
+ published_at: datetime
+ symbols: list[str] = []
+ sentiment: float
+ category: NewsCategory
+ raw_data: dict = {}
+ created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
diff --git a/shared/src/shared/sentiment_models.py b/shared/src/shared/sentiment_models.py
new file mode 100644
index 0000000..a009601
--- /dev/null
+++ b/shared/src/shared/sentiment_models.py
@@ -0,0 +1,44 @@
+"""Sentiment scoring and stock selection models."""
+
+from datetime import datetime
+from typing import Optional
+
+from pydantic import BaseModel
+
+from shared.models import OrderSide
+
+
+class SymbolScore(BaseModel):
+ symbol: str
+ news_score: float
+ news_count: int
+ social_score: float
+ policy_score: float
+ filing_score: float
+ composite: float
+ updated_at: datetime
+
+
+class MarketSentiment(BaseModel):
+ fear_greed: int
+ fear_greed_label: str
+ vix: Optional[float] = None
+ fed_stance: str
+ market_regime: str
+ updated_at: datetime
+
+
+class SelectedStock(BaseModel):
+ symbol: str
+ side: OrderSide
+ conviction: float
+ reason: str
+ key_news: list[str]
+
+
+class Candidate(BaseModel):
+ symbol: str
+ source: str
+ direction: Optional[OrderSide] = None
+ score: float
+ reason: str