summaryrefslogtreecommitdiff
path: root/shared/tests/test_sentiment_aggregator.py
diff options
context:
space:
mode:
authorTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-04-02 14:07:45 +0900
committerTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-04-02 14:07:45 +0900
commit9bf5aef24d83065c093d8cf4e32d789efd07777b (patch)
tree138bdfeec1b2f89e53458da4b2862a48b4523173 /shared/tests/test_sentiment_aggregator.py
parent5e2d5887d1f6bc7919948e3f269cfa00e243cb9f (diff)
feat: implement SentimentAggregator with freshness decay and composite scoring
Diffstat (limited to 'shared/tests/test_sentiment_aggregator.py')
-rw-r--r--shared/tests/test_sentiment_aggregator.py69
1 files changed, 69 insertions, 0 deletions
diff --git a/shared/tests/test_sentiment_aggregator.py b/shared/tests/test_sentiment_aggregator.py
new file mode 100644
index 0000000..f9277e7
--- /dev/null
+++ b/shared/tests/test_sentiment_aggregator.py
@@ -0,0 +1,69 @@
+"""Tests for sentiment aggregator."""
+import pytest
+from datetime import datetime, timezone, timedelta
+from shared.sentiment import SentimentAggregator
+
+
+@pytest.fixture
+def aggregator():
+ return SentimentAggregator()
+
+
+def test_freshness_decay_recent():
+ a = SentimentAggregator()
+ now = datetime.now(timezone.utc)
+ assert a._freshness_decay(now, now) == 1.0
+
+
+def test_freshness_decay_3_hours():
+ a = SentimentAggregator()
+ now = datetime.now(timezone.utc)
+ assert a._freshness_decay(now - timedelta(hours=3), now) == 0.7
+
+
+def test_freshness_decay_12_hours():
+ a = SentimentAggregator()
+ now = datetime.now(timezone.utc)
+ assert a._freshness_decay(now - timedelta(hours=12), now) == 0.3
+
+
+def test_freshness_decay_old():
+ a = SentimentAggregator()
+ now = datetime.now(timezone.utc)
+ assert a._freshness_decay(now - timedelta(days=2), now) == 0.0
+
+
+def test_compute_composite():
+ a = SentimentAggregator()
+ composite = a._compute_composite(news_score=0.5, social_score=0.3, policy_score=0.8, filing_score=0.2)
+ expected = 0.5 * 0.3 + 0.3 * 0.2 + 0.8 * 0.3 + 0.2 * 0.2
+ assert abs(composite - expected) < 0.001
+
+
+def test_aggregate_news_by_symbol(aggregator):
+ now = datetime.now(timezone.utc)
+ news_items = [
+ {"symbols": ["AAPL"], "sentiment": 0.8, "category": "earnings", "published_at": now},
+ {"symbols": ["AAPL"], "sentiment": 0.3, "category": "macro", "published_at": now - timedelta(hours=2)},
+ {"symbols": ["MSFT"], "sentiment": -0.5, "category": "policy", "published_at": now},
+ ]
+ scores = aggregator.aggregate(news_items, now)
+ assert "AAPL" in scores
+ assert "MSFT" in scores
+ assert scores["AAPL"].news_count == 2
+ assert scores["AAPL"].news_score > 0
+ assert scores["MSFT"].policy_score < 0
+
+
+def test_aggregate_empty(aggregator):
+ now = datetime.now(timezone.utc)
+ assert aggregator.aggregate([], now) == {}
+
+
+def test_determine_regime():
+ a = SentimentAggregator()
+ assert a.determine_regime(15, None) == "risk_off"
+ assert a.determine_regime(15, 35.0) == "risk_off"
+ assert a.determine_regime(50, 35.0) == "risk_off"
+ assert a.determine_regime(70, 15.0) == "risk_on"
+ assert a.determine_regime(50, 20.0) == "neutral"