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
|
"""Tests for news and sentiment models."""
from datetime import UTC, datetime
from shared.models import NewsCategory, NewsItem, OrderSide
from shared.sentiment_models import Candidate, MarketSentiment, SelectedStock, SymbolScore
def test_news_item_defaults():
item = NewsItem(
source="finnhub",
headline="Test headline",
published_at=datetime(2026, 4, 2, tzinfo=UTC),
sentiment=0.5,
category=NewsCategory.MACRO,
)
assert item.id
assert item.symbols == []
assert item.summary is None
assert item.raw_data == {}
assert item.created_at is not None
def test_news_item_with_symbols():
item = NewsItem(
source="rss",
headline="AAPL earnings beat",
published_at=datetime(2026, 4, 2, tzinfo=UTC),
sentiment=0.8,
category=NewsCategory.EARNINGS,
symbols=["AAPL"],
)
assert item.symbols == ["AAPL"]
assert item.category == NewsCategory.EARNINGS
def test_news_category_values():
assert NewsCategory.POLICY == "policy"
assert NewsCategory.EARNINGS == "earnings"
assert NewsCategory.MACRO == "macro"
assert NewsCategory.SOCIAL == "social"
assert NewsCategory.FILING == "filing"
assert NewsCategory.FED == "fed"
def test_symbol_score():
score = SymbolScore(
symbol="AAPL",
news_score=0.5,
news_count=10,
social_score=0.3,
policy_score=0.0,
filing_score=0.2,
composite=0.3,
updated_at=datetime(2026, 4, 2, tzinfo=UTC),
)
assert score.symbol == "AAPL"
assert score.composite == 0.3
def test_market_sentiment():
ms = MarketSentiment(
fear_greed=25,
fear_greed_label="Extreme Fear",
vix=32.5,
fed_stance="hawkish",
market_regime="risk_off",
updated_at=datetime(2026, 4, 2, tzinfo=UTC),
)
assert ms.market_regime == "risk_off"
assert ms.vix == 32.5
def test_market_sentiment_no_vix():
ms = MarketSentiment(
fear_greed=50,
fear_greed_label="Neutral",
fed_stance="neutral",
market_regime="neutral",
updated_at=datetime(2026, 4, 2, tzinfo=UTC),
)
assert ms.vix is None
def test_selected_stock():
ss = SelectedStock(
symbol="NVDA",
side=OrderSide.BUY,
conviction=0.85,
reason="CHIPS Act expansion",
key_news=["Trump signs CHIPS Act expansion"],
)
assert ss.conviction == 0.85
assert len(ss.key_news) == 1
def test_candidate():
c = Candidate(
symbol="TSLA",
source="sentiment",
direction=OrderSide.BUY,
score=0.75,
reason="High social buzz",
)
assert c.direction == OrderSide.BUY
c2 = Candidate(
symbol="XOM",
source="llm",
score=0.6,
reason="Oil price surge",
)
assert c2.direction is None
|