Finalize GTL and retire S/R research harness

This commit is contained in:
2026-07-13 17:58:04 +02:00
parent 9d362bd568
commit bee5a5ce89
35 changed files with 374 additions and 5385779 deletions
+21 -131
View File
@@ -6,14 +6,12 @@ from app.services.sr_service import (
MAX_LEVELS,
_bar_respect_weight,
_cap_levels,
_legacy_range_grid_nodes,
_legacy_volume_profile_nodes,
_gate_target_range_centers,
_merge_levels,
_round_number_candidates,
_strength_from_respects,
detect_gate_target_ladder,
detect_sr_levels,
detect_sr_levels_legacy,
)
@@ -237,134 +235,26 @@ class TestDetectSrLevels:
pinned = sum(1 for lvl in levels if lvl["strength"] == 100)
assert pinned < len(levels)
def test_legacy_control_retains_old_uncapped_grid(self):
highs, lows, closes, volumes = _make_series(n=500)
levels = detect_sr_levels_legacy(highs, lows, closes, volumes)
assert levels
assert all(level["sources"] for level in levels)
# The research control intentionally keeps the deployed detector's much
# denser output instead of borrowing the rewrite's presentation cap.
def test_gate_target_range_centers_cover_the_observed_range(self):
highs, lows, closes, _ = _make_series(n=500)
centers = _gate_target_range_centers(highs, lows, closes)
assert len(centers) == 20
assert centers == sorted(centers)
assert min(lows) < centers[0] < centers[-1] < max(highs)
def test_gate_target_ladder_is_dense_transient_price_traffic(self):
highs, lows, closes, _ = _make_series(n=500)
levels = detect_gate_target_ladder(highs, lows, closes)
assert len(levels) > MAX_LEVELS
assert any("range_grid" in level["sources"] for level in levels)
assert all("volume_profile" not in level["sources"] for level in levels)
assert all(0 <= level["strength"] <= 100 for level in levels)
assert all(level["rejection_count"] >= 0 for level in levels)
def test_legacy_geometry_neutral_changes_only_strength(self):
highs, lows, closes, volumes = _make_series(n=500)
control = detect_sr_levels_legacy(highs, lows, closes, volumes)
neutral = detect_sr_levels_legacy(
highs, lows, closes, volumes, neutral_strength=True
def test_gate_target_ladder_is_deterministic(self):
highs, lows, closes, _ = _make_series(n=500)
assert detect_gate_target_ladder(highs, lows, closes) == (
detect_gate_target_ladder(list(highs), list(lows), list(closes))
)
assert [level["price_level"] for level in neutral] == [
level["price_level"] for level in sorted(
control, key=lambda row: row["price_level"]
)
]
assert all(level["strength"] == 50 for level in neutral)
def test_legacy_source_ablation_isolates_candidates(self):
highs, lows, closes, volumes = _make_series(n=500)
pivots = detect_sr_levels_legacy(
highs, lows, closes, volumes, include_volume_profile=False
)
traffic = detect_sr_levels_legacy(
highs, lows, closes, volumes, include_pivots=False
)
assert pivots and traffic
assert all(level["sources"] == ["pivot_point"] for level in pivots)
assert all(level["sources"] == ["volume_profile"] for level in traffic)
def test_legacy_profile_union_matches_explicit_range_grid(self):
highs, lows, closes, volumes = _make_series(n=500)
deployed = _legacy_volume_profile_nodes(highs, lows, closes, volumes)
explicit = _legacy_range_grid_nodes(highs, lows, closes)
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_gate_target_ladder_is_the_explicit_volume_free_detector(self):
highs, lows, closes, volumes = _make_series(n=500)
expected = detect_sr_levels_legacy(
highs,
lows,
closes,
volumes,
explicit_range_grid=True,
)
assert detect_gate_target_ladder(highs, lows, closes) == expected
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)]
baseline = detect_sr_levels_legacy(
highs,
lows,
closes,
volumes,
include_pivots=False,
explicit_range_grid=True,
)
shifted = detect_sr_levels_legacy(
highs,
lows,
closes,
shifted_volumes,
include_pivots=False,
explicit_range_grid=True,
)
assert shifted == baseline
def test_explicit_range_grid_neutral_changes_only_strength(self):
highs, lows, closes, volumes = _make_series(n=500)
touch = detect_sr_levels_legacy(
highs,
lows,
closes,
volumes,
include_pivots=False,
explicit_range_grid=True,
)
neutral = detect_sr_levels_legacy(
highs,
lows,
closes,
volumes,
include_pivots=False,
neutral_strength=True,
explicit_range_grid=True,
)
touch_by_price = {level["price_level"]: level for level in touch}
neutral_by_price = {level["price_level"]: level for level in neutral}
assert neutral_by_price.keys() == touch_by_price.keys()
for price, neutral_level in neutral_by_price.items():
assert neutral_level["strength"] == 50
assert {
key: value
for key, value in neutral_level.items()
if key != "strength"
} == {
key: value
for key, value in touch_by_price[price].items()
if key != "strength"
}