feat: technical, news, and social analysis agents
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
31
tests/test_news_agent.py
Normal file
31
tests/test_news_agent.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import pytest
|
||||
from agents.news import NewsAgent
|
||||
|
||||
def test_score_positive_news():
|
||||
agent = NewsAgent()
|
||||
articles = [
|
||||
{"title": "Bitcoin surges 10%", "sentiment_votes": {"positive": 10, "negative": 1}},
|
||||
{"title": "BTC adoption grows", "sentiment_votes": {"positive": 8, "negative": 2}},
|
||||
{"title": "Bitcoin rally continues", "sentiment_votes": {"positive": 15, "negative": 0}},
|
||||
]
|
||||
score = agent.analyze(articles)
|
||||
assert score >= 70
|
||||
|
||||
def test_score_negative_news():
|
||||
agent = NewsAgent()
|
||||
articles = [
|
||||
{"title": "Bitcoin crashes hard", "sentiment_votes": {"positive": 1, "negative": 10}},
|
||||
{"title": "Crypto market in fear", "sentiment_votes": {"positive": 0, "negative": 15}},
|
||||
]
|
||||
score = agent.analyze(articles)
|
||||
assert score <= 35
|
||||
|
||||
def test_score_no_news_returns_50():
|
||||
agent = NewsAgent()
|
||||
assert agent.analyze([]) == 50
|
||||
|
||||
def test_score_mixed_news():
|
||||
agent = NewsAgent()
|
||||
articles = [{"title": "BTC up", "sentiment_votes": {"positive": 5, "negative": 5}}]
|
||||
score = agent.analyze(articles)
|
||||
assert 40 <= score <= 60
|
||||
19
tests/test_social_agent.py
Normal file
19
tests/test_social_agent.py
Normal file
@@ -0,0 +1,19 @@
|
||||
import pytest
|
||||
from agents.social import SocialAgent
|
||||
|
||||
def test_score_bullish_social():
|
||||
agent = SocialAgent()
|
||||
sentiment = {"positive": 8, "negative": 1, "neutral": 1, "total": 10}
|
||||
score = agent.analyze(sentiment, mention_trend=2.5)
|
||||
assert score >= 70
|
||||
|
||||
def test_score_bearish_social():
|
||||
agent = SocialAgent()
|
||||
sentiment = {"positive": 1, "negative": 8, "neutral": 1, "total": 10}
|
||||
score = agent.analyze(sentiment, mention_trend=0.5)
|
||||
assert score <= 35
|
||||
|
||||
def test_no_data_returns_50():
|
||||
agent = SocialAgent()
|
||||
score = agent.analyze({"positive": 0, "negative": 0, "neutral": 0, "total": 0}, 1.0)
|
||||
assert score == 50
|
||||
58
tests/test_technical.py
Normal file
58
tests/test_technical.py
Normal file
@@ -0,0 +1,58 @@
|
||||
import pytest
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from agents.technical import TechnicalAgent
|
||||
|
||||
def make_ohlcv(n=100, base_price=100.0):
|
||||
np.random.seed(42)
|
||||
closes = base_price + np.cumsum(np.random.randn(n) * 2)
|
||||
df = pd.DataFrame({
|
||||
"timestamp": pd.date_range("2026-01-01", periods=n, freq="1h"),
|
||||
"open": closes - np.random.rand(n),
|
||||
"high": closes + np.abs(np.random.randn(n) * 2),
|
||||
"low": closes - np.abs(np.random.randn(n) * 2),
|
||||
"close": closes,
|
||||
"volume": np.random.randint(100, 10000, n).astype(float),
|
||||
"quote_volume": np.random.randint(100000, 1000000, n).astype(float),
|
||||
})
|
||||
return df
|
||||
|
||||
def test_score_returns_0_to_100():
|
||||
agent = TechnicalAgent()
|
||||
df = make_ohlcv(100)
|
||||
score = agent.analyze(df)
|
||||
assert 0 <= score <= 100
|
||||
|
||||
def test_score_with_uptrend():
|
||||
agent = TechnicalAgent()
|
||||
n = 100
|
||||
closes = np.linspace(100, 200, n)
|
||||
df = pd.DataFrame({
|
||||
"timestamp": pd.date_range("2026-01-01", periods=n, freq="1h"),
|
||||
"open": closes - 1, "high": closes + 2,
|
||||
"low": closes - 2, "close": closes,
|
||||
"volume": np.full(n, 5000.0),
|
||||
"quote_volume": np.full(n, 500000.0),
|
||||
})
|
||||
score = agent.analyze(df)
|
||||
assert score >= 55 # uptrend should score above average
|
||||
|
||||
def test_score_with_downtrend():
|
||||
agent = TechnicalAgent()
|
||||
n = 100
|
||||
closes = np.linspace(200, 100, n)
|
||||
df = pd.DataFrame({
|
||||
"timestamp": pd.date_range("2026-01-01", periods=n, freq="1h"),
|
||||
"open": closes + 1, "high": closes + 2,
|
||||
"low": closes - 2, "close": closes,
|
||||
"volume": np.full(n, 5000.0),
|
||||
"quote_volume": np.full(n, 500000.0),
|
||||
})
|
||||
score = agent.analyze(df)
|
||||
assert score <= 45 # downtrend should score below average
|
||||
|
||||
def test_insufficient_data_returns_50():
|
||||
agent = TechnicalAgent()
|
||||
df = make_ohlcv(5)
|
||||
score = agent.analyze(df)
|
||||
assert score == 50
|
||||
Reference in New Issue
Block a user