148 lines
4.6 KiB
Python
148 lines
4.6 KiB
Python
|
|
"""Tests for output schemas"""
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
from sentiment_engine.schemas.output import (
|
||
|
|
AssetSentiment, MarketSentiment, IndustrySentiment, SentimentOutput,
|
||
|
|
PumpDumpScore, VelocityMetrics, EventFlag
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
class TestPumpDumpScore:
|
||
|
|
"""Tests for PumpDumpScore"""
|
||
|
|
|
||
|
|
def test_valid_score(self):
|
||
|
|
score = PumpDumpScore(
|
||
|
|
asset_id="BTC",
|
||
|
|
pump_score=75.0,
|
||
|
|
dump_score=15.0,
|
||
|
|
pump_confidence=0.8,
|
||
|
|
dump_confidence=0.7,
|
||
|
|
coordinating_sources=3,
|
||
|
|
last_update_ts=1234567890.0
|
||
|
|
)
|
||
|
|
assert score.asset_id == "BTC"
|
||
|
|
assert score.pump_score == 75.0
|
||
|
|
|
||
|
|
def test_bounds_check(self):
|
||
|
|
with pytest.raises(ValueError):
|
||
|
|
PumpDumpScore(
|
||
|
|
asset_id="BTC",
|
||
|
|
pump_score=150.0, # > 100
|
||
|
|
dump_score=15.0,
|
||
|
|
pump_confidence=0.8,
|
||
|
|
dump_confidence=0.7,
|
||
|
|
last_update_ts=1234567890.0
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
class TestVelocityMetrics:
|
||
|
|
"""Tests for VelocityMetrics"""
|
||
|
|
|
||
|
|
def test_valid_metrics(self):
|
||
|
|
vel = VelocityMetrics(
|
||
|
|
hype_velocity=0.7,
|
||
|
|
pub_velocity=0.5,
|
||
|
|
velocity_direction="accelerating",
|
||
|
|
window_minutes=15,
|
||
|
|
source_count=3,
|
||
|
|
unique_assets=1
|
||
|
|
)
|
||
|
|
assert vel.hype_velocity == 0.7
|
||
|
|
assert vel.velocity_direction == "accelerating"
|
||
|
|
|
||
|
|
|
||
|
|
class TestEventFlag:
|
||
|
|
"""Tests for EventFlag"""
|
||
|
|
|
||
|
|
def test_valid_flag(self):
|
||
|
|
flag = EventFlag(
|
||
|
|
event_type="listing",
|
||
|
|
asset_id="BTC",
|
||
|
|
strength=60.0,
|
||
|
|
confidence=0.7,
|
||
|
|
first_seen_ts=1234567890.0,
|
||
|
|
last_seen_ts=1234567895.0,
|
||
|
|
source_count=2
|
||
|
|
)
|
||
|
|
assert flag.event_type == "listing"
|
||
|
|
assert flag.strength == 60.0
|
||
|
|
|
||
|
|
|
||
|
|
class TestAssetSentiment:
|
||
|
|
"""Tests for AssetSentiment"""
|
||
|
|
|
||
|
|
def test_valid_asset_sentiment(self):
|
||
|
|
asset = AssetSentiment(
|
||
|
|
asset_id="BTC",
|
||
|
|
fear_state=20.0,
|
||
|
|
greed_state=80.0,
|
||
|
|
sentiment_polarity=60.0,
|
||
|
|
emotion_profile={"joy": 0.8, "fear": 0.1, "anger": 0.05, "greed": 0.7, "sadness": 0.05, "intensity": 0.75},
|
||
|
|
last_update_ts=1234567890.0,
|
||
|
|
contributing_sources=3
|
||
|
|
)
|
||
|
|
assert asset.asset_id == "BTC"
|
||
|
|
assert asset.fear_state == 20.0
|
||
|
|
|
||
|
|
def test_acb_signals(self):
|
||
|
|
from sentiment_engine.schemas.output import MarketSentiment, SentimentOutput
|
||
|
|
market = MarketSentiment(
|
||
|
|
fear_state=25.0,
|
||
|
|
greed_state=75.0,
|
||
|
|
sentiment_index=50.0,
|
||
|
|
hype_velocity=65.0,
|
||
|
|
pub_velocity=55.0,
|
||
|
|
aggregate_pump_risk=75.0,
|
||
|
|
aggregate_dump_risk=20.0,
|
||
|
|
last_update_ts=1234567890.0
|
||
|
|
)
|
||
|
|
output = SentimentOutput(timestamp=1234567890.0, market=market)
|
||
|
|
|
||
|
|
acb = output.get_acb_signals()
|
||
|
|
assert "market_sentiment_state" in acb
|
||
|
|
assert "aggregate_pump_risk" in acb
|
||
|
|
assert -1.0 <= acb["market_sentiment_state"] <= 1.0
|
||
|
|
assert 0.0 <= acb["aggregate_pump_risk"] <= 1.0
|
||
|
|
|
||
|
|
def test_book_health_veto(self):
|
||
|
|
from sentiment_engine.schemas.output import MarketSentiment, SentimentOutput, PumpDumpScore
|
||
|
|
asset = AssetSentiment(
|
||
|
|
asset_id="BTC",
|
||
|
|
fear_state=20.0,
|
||
|
|
greed_state=80.0,
|
||
|
|
sentiment_polarity=60.0,
|
||
|
|
pump_dump=PumpDumpScore(asset_id="BTC", pump_score=80.0, dump_score=15.0, pump_confidence=0.8, dump_confidence=0.7, last_update_ts=1234567890.0),
|
||
|
|
last_update_ts=1234567890.0
|
||
|
|
)
|
||
|
|
market = MarketSentiment(
|
||
|
|
fear_state=25.0, greed_state=75.0, sentiment_index=50.0,
|
||
|
|
hype_velocity=65.0, pub_velocity=55.0,
|
||
|
|
aggregate_pump_risk=75.0, aggregate_dump_risk=20.0,
|
||
|
|
last_update_ts=1234567890.0
|
||
|
|
)
|
||
|
|
output = SentimentOutput(timestamp=1234567890.0, market=market, assets={"BTC": asset})
|
||
|
|
|
||
|
|
veto = output.get_book_health_veto(threshold=75.0)
|
||
|
|
assert "BTC" in veto
|
||
|
|
|
||
|
|
veto_low = output.get_book_health_veto(threshold=85.0)
|
||
|
|
assert "BTC" not in veto_low
|
||
|
|
|
||
|
|
|
||
|
|
class TestMarketSentiment:
|
||
|
|
"""Tests for MarketSentiment"""
|
||
|
|
|
||
|
|
def test_valid_market(self):
|
||
|
|
market = MarketSentiment(
|
||
|
|
fear_state=25.0,
|
||
|
|
greed_state=75.0,
|
||
|
|
sentiment_index=50.0,
|
||
|
|
hype_velocity=65.0,
|
||
|
|
pub_velocity=55.0,
|
||
|
|
aggregate_pump_risk=75.0,
|
||
|
|
aggregate_dump_risk=20.0,
|
||
|
|
last_update_ts=1234567890.0
|
||
|
|
)
|
||
|
|
assert market.fear_state == 25.0
|
||
|
|
assert market.sentiment_index == 50.0
|