"""Unit tests for market feature calculations.""" from libs.oracle_client.models import PriceBar BARS = [ PriceBar(date="2026-01-26", open=227.5, high=230.0, low=226.0, close=229.5, volume=48000000), PriceBar(date="2026-01-27", open=229.0, high=232.0, low=228.0, close=231.0, volume=55000000), PriceBar(date="2026-01-28", open=231.5, high=234.0, low=230.0, close=233.0, volume=60000000), PriceBar(date="2026-01-29", open=240.0, high=245.0, low=238.0, close=243.0, volume=120000000), ] def test_reaction_day_return(): from libs.features.market_features import reaction_day_return r = reaction_day_return(BARS, "2026-01-29") assert r is not None expected = (243.0 - 233.0) / 233.0 assert abs(r - expected) < 1e-6 def test_reaction_day_return_missing_date(): from libs.features.market_features import reaction_day_return assert reaction_day_return(BARS, "2026-12-01") is None def test_volume_ratio_20d(): from libs.features.market_features import volume_ratio_20d r = volume_ratio_20d(BARS, "2026-01-29") assert r is not None avg = (48000000 + 55000000 + 60000000) / 3 assert abs(r - 120000000 / avg) < 1e-3 def test_close_location(): from libs.features.market_features import close_location bar = PriceBar(date="2026-01-29", open=240.0, high=245.0, low=238.0, close=243.0, volume=120000000) cl = close_location(bar) assert cl is not None expected = (243.0 - 238.0) / (245.0 - 238.0) assert abs(cl - expected) < 1e-6 def test_close_location_zero_range(): from libs.features.market_features import close_location bar = PriceBar(date="2026-01-29", open=100.0, high=100.0, low=100.0, close=100.0, volume=1000) assert close_location(bar) is None def test_gap_size(): from libs.features.market_features import gap_size g = gap_size(BARS, "2026-01-29") assert g is not None expected = (240.0 - 233.0) / 233.0 assert abs(g - expected) < 1e-6 def test_atr_14(): from libs.features.market_features import atr_14 # With fewer than 14 bars, should still return avg TR r = atr_14(BARS) assert r is not None assert r > 0 def test_compute_market_features_dict(): from libs.features.market_features import compute_market_features features = compute_market_features(BARS, "2026-01-29") assert "reaction_day_return" in features assert "volume_ratio_20d" in features assert "gap_size" in features assert "atr_14" in features assert "close_location" in features