Separate chart S/R from gate target ladder
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user