Separate chart S/R from gate target ladder

This commit is contained in:
2026-07-13 11:17:03 +02:00
parent 995a0380c3
commit 8161c352a0
12 changed files with 277 additions and 58 deletions
+66 -1
View File
@@ -8,6 +8,7 @@ correct TradeSetup field population, and database persistence.
from __future__ import annotations
import json
from datetime import date, datetime, timedelta, timezone
import pytest
@@ -152,7 +153,13 @@ async def test_scan_ticker_full_flow_quality_selection_and_persistence(
assert len(pre_setups) == 1, "Dummy old setup should exist before scan"
# -- Act: run scan_ticker --
setups = await scan_ticker(scan_session, "INTEG", rr_threshold=1.5, atr_multiplier=1.5)
setups = await scan_ticker(
scan_session,
"INTEG",
rr_threshold=1.5,
atr_multiplier=1.5,
gate_levels_override=sr_levels,
)
# -- Assert: both directions produced --
assert len(setups) == 2, f"Expected 2 setups (long + short), got {len(setups)}"
@@ -255,3 +262,61 @@ async def test_scan_ticker_full_flow_quality_selection_and_persistence(
assert persisted_short.entry_price == short_setup.entry_price
assert persisted_short.stop_loss == short_setup.stop_loss
assert persisted_short.composite_score == short_setup.composite_score
@pytest.mark.asyncio
async def test_scan_ticker_uses_transient_ladder_not_persisted_chart_levels(
scan_session: AsyncSession,
monkeypatch,
):
ticker = Ticker(symbol="DUAL")
scan_session.add(ticker)
await scan_session.flush()
scan_session.add_all(_make_ohlcv_bars(ticker.id, num_bars=20, base_close=100.0))
scan_session.add(SRLevel(
ticker_id=ticker.id,
price_level=130.0,
type="resistance",
strength=100,
detection_method="pivot_point",
))
await scan_session.commit()
ladder = [
{
"price_level": 105.0,
"type": "resistance",
"strength": 90,
"detection_method": "range_grid",
"sources": ["range_grid"],
"rejection_count": 5,
"last_rejection_age": None,
},
{
"price_level": 95.0,
"type": "support",
"strength": 85,
"detection_method": "range_grid",
"sources": ["range_grid"],
"rejection_count": 4,
"last_rejection_age": None,
},
]
monkeypatch.setattr(
"app.services.rr_scanner_service.detect_gate_target_ladder",
lambda highs, lows, closes: ladder,
)
setups = await scan_ticker(
scan_session,
"DUAL",
rr_threshold=1.5,
)
long_setup = next(setup for setup in setups if setup.direction == "long")
assert long_setup.target == pytest.approx(105.0, abs=0.01)
assert long_setup.target != pytest.approx(130.0, abs=0.01)
targets = json.loads(long_setup.targets_json or "[]")
assert targets
assert all(target["sr_level_id"] < 0 for target in targets)
assert all(target["sr_sources"] == ["range_grid"] for target in targets)