Fix post-cluster neutral strength ablation
This commit is contained in:
@@ -156,6 +156,28 @@ def _sr_research_variant() -> str:
|
||||
return value
|
||||
|
||||
|
||||
def _apply_zone_strength_variant(zone_levels: list[Any], sr_variant: str) -> list[Any]:
|
||||
"""Apply post-cluster research controls without changing zone geometry."""
|
||||
if sr_variant == "legacy_geometry_neutral":
|
||||
# Neutrality must be enforced after the shared zone cluster: its legacy
|
||||
# sum mode can otherwise turn two 50-strength constituents back into a
|
||||
# 100-strength target and silently invalidate the ablation.
|
||||
for level in zone_levels:
|
||||
level.strength = 50
|
||||
return zone_levels
|
||||
|
||||
|
||||
def _apply_zone_strength_variant(zone_levels: list[Any], sr_variant: str) -> list[Any]:
|
||||
"""Apply post-cluster research controls without changing zone geometry."""
|
||||
if sr_variant == "legacy_geometry_neutral":
|
||||
# Neutrality must be enforced after the shared zone cluster: its legacy
|
||||
# sum mode can otherwise turn two 50-strength constituents back into a
|
||||
# 100-strength target and silently invalidate the ablation.
|
||||
for level in zone_levels:
|
||||
level.strength = 50
|
||||
return zone_levels
|
||||
|
||||
|
||||
def _backtest_entry_bounds() -> tuple[date | None, date | None]:
|
||||
"""Optional research-only entry bounds used to protect validation data."""
|
||||
parsed: list[date | None] = []
|
||||
@@ -328,6 +350,8 @@ def _window_setups(
|
||||
entry,
|
||||
strength_mode=zone_strength_mode,
|
||||
)
|
||||
zone_levels = _apply_zone_strength_variant(zone_levels, sr_variant)
|
||||
zone_levels = _apply_zone_strength_variant(zone_levels, sr_variant)
|
||||
targets = target_generator.generate_targets(direction, entry, stop, zone_levels, atr)
|
||||
if not targets:
|
||||
fallback_k = _atr_target_fallback_k()
|
||||
|
||||
@@ -498,6 +498,29 @@ Run on macOS:
|
||||
Do not validate any traffic arm yet. First establish whether geometry, pivots, or
|
||||
the range-occupancy grid reproduces production on pre-2024 training data.
|
||||
|
||||
Initial result:
|
||||
|
||||
| arm | Sharpe | CAGR | MaxDD | net avg R | ex-top-5% |
|
||||
|---|---:|---:|---:|---:|---:|
|
||||
| production control | 1.28 | 28.8% | 21.4% | 0.230 | 0.066 |
|
||||
| pivots only | 1.38 | 32.9% | 25.2% | 0.236 | 0.076 |
|
||||
| traffic grid only | **1.72** | **41.8%** | **16.8%** | **0.271** | **0.136** |
|
||||
|
||||
The traffic grid is the first research arm to beat control simultaneously on
|
||||
Sharpe, CAGR, drawdown, and robust expectancy. It retains 264 production setups,
|
||||
adds 240 positive-expectancy setups, and removes 412 weaker setups. This supports
|
||||
the hypothesis that the useful legacy feature is the volume-weighted range-
|
||||
occupancy grid, not pivots or visually meaningful S/R.
|
||||
|
||||
The first geometry-neutral result is not interpretable: neutral strength was set
|
||||
before the shared zone cluster, which summed multiple 50-strength constituents
|
||||
back to 100. Neutrality is now enforced after clustering. Rerun only that arm:
|
||||
|
||||
```bash
|
||||
.venv/bin/python scripts/run_sr_v2_matrix.py traffic \
|
||||
--only-arm legacy_geometry_neutral --workers 14
|
||||
```
|
||||
|
||||
**Next runs, if picked back up:**
|
||||
|
||||
- A **per-name target model** for clear-air setups instead of a constant k×ATR. This
|
||||
|
||||
@@ -50,6 +50,12 @@ def _args() -> argparse.Namespace:
|
||||
help="Isolate legacy geometry, pivots, and price-traffic grid on training data.",
|
||||
)
|
||||
_add_common(traffic)
|
||||
traffic.add_argument(
|
||||
"--only-arm",
|
||||
choices=TRAFFIC_ARMS,
|
||||
default=None,
|
||||
help="Rerun one hidden-feature arm without repeating the full matrix.",
|
||||
)
|
||||
validate = commands.add_parser(
|
||||
"validate",
|
||||
help="Run production control and one locked arm from 2024-07-01.",
|
||||
@@ -135,7 +141,8 @@ def main() -> None:
|
||||
if args.command == "train":
|
||||
_train(args, TRAINING_ARMS, "backtest-sr-v2-train")
|
||||
elif args.command == "traffic":
|
||||
_train(args, TRAFFIC_ARMS, "backtest-sr-traffic-train")
|
||||
arms = (args.only_arm,) if args.only_arm else TRAFFIC_ARMS
|
||||
_train(args, arms, "backtest-sr-traffic-train")
|
||||
else:
|
||||
_validate(args)
|
||||
|
||||
|
||||
@@ -766,6 +766,15 @@ def test_sr_research_variant_is_explicit_and_validated(monkeypatch):
|
||||
bt._sr_research_variant()
|
||||
|
||||
|
||||
def test_geometry_neutral_strength_is_enforced_after_zone_clustering():
|
||||
levels = [
|
||||
SimpleNamespace(strength=100),
|
||||
SimpleNamespace(strength=75),
|
||||
]
|
||||
result = bt._apply_zone_strength_variant(levels, "legacy_geometry_neutral")
|
||||
assert [level.strength for level in result] == [50, 50]
|
||||
|
||||
|
||||
def test_backtest_entry_bounds_validate_dates(monkeypatch):
|
||||
monkeypatch.setenv("BACKTEST_ENTRY_START", "2024-07-01")
|
||||
monkeypatch.setenv("BACKTEST_ENTRY_END", "2024-12-31")
|
||||
|
||||
Reference in New Issue
Block a user