Isolate explicit S/R gate target ladder
This commit is contained in:
@@ -802,6 +802,7 @@ def test_sr_research_variant_is_explicit_and_validated(monkeypatch):
|
||||
"rewrite_range504_structural_legacy_primary",
|
||||
"rewrite_range504_structural_primary2",
|
||||
"production_structural_overlay",
|
||||
"explicit_target_ladder",
|
||||
):
|
||||
monkeypatch.setenv("BACKTEST_SR_VARIANT", variant)
|
||||
assert bt._sr_research_variant() == variant
|
||||
@@ -856,6 +857,10 @@ def test_residual_arms_change_only_the_primary_rr_floor():
|
||||
"production_structural_overlay",
|
||||
activation,
|
||||
) == 1.5
|
||||
assert bt._primary_min_rr_for_variant(
|
||||
"explicit_target_ladder",
|
||||
activation,
|
||||
) == 1.5
|
||||
|
||||
|
||||
def test_structural_overlay_tags_production_geometry_without_replacing_it(monkeypatch):
|
||||
@@ -934,6 +939,31 @@ def test_window_setups_routes_explicit_range_grid(
|
||||
}
|
||||
|
||||
|
||||
def test_window_setups_routes_full_explicit_target_ladder(monkeypatch):
|
||||
captured = {}
|
||||
|
||||
def fake_detector(*args, **kwargs):
|
||||
captured.update(kwargs)
|
||||
return []
|
||||
|
||||
monkeypatch.setenv("BACKTEST_SR_VARIANT", bt.EXPLICIT_TARGET_LADDER_VARIANT)
|
||||
monkeypatch.setattr(bt, "detect_sr_levels_legacy", fake_detector)
|
||||
records = [
|
||||
SimpleNamespace(
|
||||
date=date(2024, 1, 1) + timedelta(days=i),
|
||||
open=100.0,
|
||||
high=101.0,
|
||||
low=99.0,
|
||||
close=100.0,
|
||||
volume=1_000_000,
|
||||
)
|
||||
for i in range(bt.MIN_LOOKBACK)
|
||||
]
|
||||
|
||||
assert bt._window_setups(records, {}, {}) == []
|
||||
assert captured == {"explicit_range_grid": True}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"variant",
|
||||
["legacy_geometry_neutral", "legacy_range_grid_neutral"],
|
||||
|
||||
@@ -277,6 +277,30 @@ class TestDetectSrLevels:
|
||||
assert sorted(deployed) == explicit
|
||||
assert len(explicit) == 20
|
||||
|
||||
def test_explicit_target_ladder_preserves_full_legacy_mechanics(self):
|
||||
highs, lows, closes, volumes = _make_series(n=500)
|
||||
deployed = detect_sr_levels_legacy(highs, lows, closes, volumes)
|
||||
explicit = detect_sr_levels_legacy(
|
||||
highs,
|
||||
lows,
|
||||
closes,
|
||||
volumes,
|
||||
explicit_range_grid=True,
|
||||
)
|
||||
|
||||
def mechanics(level):
|
||||
return {
|
||||
key: value
|
||||
for key, value in level.items()
|
||||
if key not in {"detection_method", "sources"}
|
||||
}
|
||||
|
||||
assert [mechanics(level) for level in explicit] == [
|
||||
mechanics(level) for level in deployed
|
||||
]
|
||||
assert any("range_grid" in level["sources"] for level in explicit)
|
||||
assert all("volume_profile" not in level["sources"] for level in explicit)
|
||||
|
||||
def test_explicit_range_grid_is_volume_independent(self):
|
||||
highs, lows, closes, volumes = _make_series(n=500)
|
||||
shifted_volumes = [volume * (i + 1) for i, volume in enumerate(volumes)]
|
||||
|
||||
Reference in New Issue
Block a user