from app.analysis.horizontals import build_prior_day_levels from app.bars.models import Bar, Timeframe def daily(t: int, o: float, h: float, low: float, c: float, closed: bool = True) -> Bar: return Bar(Timeframe.D1, t, o, h, low, c, 1000, closed, "ES=F", "test") def test_prior_day_uses_last_closed_session_not_the_forming_one(): bars = [ daily(1, 100, 110, 90, 105), daily(2, 105, 120, 100, 118), daily(3, 118, 125, 117, 124, closed=False), ] levels = {level.id: level for level in build_prior_day_levels(bars, current_price=119)} # The forming session's 125 high must not become "prior day high" mid-session. assert levels["pd:high"].anchor_p == 120 assert levels["pd:low"].anchor_p == 100 assert levels["pd:close"].anchor_p == 118 def test_side_is_positional_against_current_price(): bars = [daily(1, 100, 110, 90, 105)] levels = {level.id: level for level in build_prior_day_levels(bars, current_price=100)} assert levels["pd:high"].side.value == "resistance" assert levels["pd:low"].side.value == "support" def test_prior_day_carries_full_daily_weight_not_the_average_discount(): levels = build_prior_day_levels([daily(1, 100, 110, 90, 105)], current_price=100) # Traded structure, not a derived average, so no 0.75 factor. assert all(level.weight == 16 for level in levels) def test_no_closed_session_yields_nothing(): assert build_prior_day_levels([daily(1, 100, 110, 90, 105, closed=False)], 100) == []