Separate S/R detector tests from primary R:R policy
This commit is contained in:
@@ -137,6 +137,10 @@ SR_RESEARCH_VARIANTS = {
|
|||||||
"soft_zones",
|
"soft_zones",
|
||||||
"confirmed_rounds",
|
"confirmed_rounds",
|
||||||
"gate_v2",
|
"gate_v2",
|
||||||
|
"rewrite_legacy_primary",
|
||||||
|
"soft_zones_legacy_primary",
|
||||||
|
"confirmed_rounds_legacy_primary",
|
||||||
|
"gate_v2_legacy_primary",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -268,10 +272,11 @@ def _window_setups(
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
sr_variant = _sr_research_variant()
|
sr_variant = _sr_research_variant()
|
||||||
if sr_variant in {"production_control", "rr_aligned_control"}:
|
detector_variant = sr_variant.removesuffix("_legacy_primary")
|
||||||
|
if detector_variant in {"production_control", "rr_aligned_control"}:
|
||||||
detected_levels = detect_sr_levels_legacy(highs, lows, closes, volumes)
|
detected_levels = detect_sr_levels_legacy(highs, lows, closes, volumes)
|
||||||
else:
|
else:
|
||||||
detector_cap = 0 if sr_variant == "gate_v2" else MAX_LEVELS
|
detector_cap = 0 if detector_variant == "gate_v2" else MAX_LEVELS
|
||||||
detected_levels = detect_sr_levels(
|
detected_levels = detect_sr_levels(
|
||||||
highs, lows, closes, volumes, max_levels=detector_cap
|
highs, lows, closes, volumes, max_levels=detector_cap
|
||||||
)
|
)
|
||||||
@@ -281,11 +286,11 @@ def _window_setups(
|
|||||||
|
|
||||||
gate_levels = _gate_eligible_levels(
|
gate_levels = _gate_eligible_levels(
|
||||||
sr_levels,
|
sr_levels,
|
||||||
confirmed_rounds_only=sr_variant in {"confirmed_rounds", "gate_v2"},
|
confirmed_rounds_only=detector_variant in {"confirmed_rounds", "gate_v2"},
|
||||||
)
|
)
|
||||||
zone_strength_mode = (
|
zone_strength_mode = (
|
||||||
"soft"
|
"soft"
|
||||||
if sr_variant in {"soft_zones", "confirmed_rounds", "gate_v2"}
|
if detector_variant in {"soft_zones", "confirmed_rounds", "gate_v2"}
|
||||||
else "sum"
|
else "sum"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -326,7 +331,7 @@ def _window_setups(
|
|||||||
targets = _prune_floor_pinned_targets(targets)
|
targets = _prune_floor_pinned_targets(targets)
|
||||||
primary_min_rr = (
|
primary_min_rr = (
|
||||||
1.5
|
1.5
|
||||||
if sr_variant == "production_control"
|
if sr_variant == "production_control" or sr_variant.endswith("_legacy_primary")
|
||||||
else float(activation.get("min_rr", 0.0))
|
else float(activation.get("min_rr", 0.0))
|
||||||
)
|
)
|
||||||
primary = _select_primary_target(
|
primary = _select_primary_target(
|
||||||
|
|||||||
@@ -436,6 +436,17 @@ calls `scripts/compare_sr_variants.py` to produce the paired cohort CSV and JSON
|
|||||||
> the test period. The simulator now treats `BACKTEST_ENTRY_END` as an inclusive
|
> the test period. The simulator now treats `BACKTEST_ENTRY_END` as an inclusive
|
||||||
> entry bound and truncates the calendar after the final position can resolve.
|
> entry bound and truncates the calendar after the final position can resolve.
|
||||||
|
|
||||||
|
The isolated `rr_aligned_control` validation also failed (Sharpe 2.78 to 1.32,
|
||||||
|
CAGR 73.3% to 33.1%, drawdown 11.7% to 18.4%). The live 1.5 primary-selection
|
||||||
|
behavior is therefore frozen: although it predates the 2.0 activation gate, it
|
||||||
|
acts as a useful selectivity mechanism. The final detector matrix holds that
|
||||||
|
behavior constant and varies only detection/zone policy:
|
||||||
|
|
||||||
|
- `rewrite_legacy_primary`
|
||||||
|
- `soft_zones_legacy_primary`
|
||||||
|
- `confirmed_rounds_legacy_primary`
|
||||||
|
- `gate_v2_legacy_primary`
|
||||||
|
|
||||||
The post-2024 interval has informed earlier research, so this is validation rather
|
The post-2024 interval has informed earlier research, so this is validation rather
|
||||||
than a pristine holdout; do not sweep variants on it. No deployment follows
|
than a pristine holdout; do not sweep variants on it. No deployment follows
|
||||||
automatically. A lower validation Sharpe or higher drawdown remains a no-ship
|
automatically. A lower validation Sharpe or higher drawdown remains a no-ship
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ def _parse_args() -> argparse.Namespace:
|
|||||||
choices=(
|
choices=(
|
||||||
"production_control", "rr_aligned_control", "rewrite",
|
"production_control", "rr_aligned_control", "rewrite",
|
||||||
"soft_zones", "confirmed_rounds", "gate_v2",
|
"soft_zones", "confirmed_rounds", "gate_v2",
|
||||||
|
"rewrite_legacy_primary", "soft_zones_legacy_primary",
|
||||||
|
"confirmed_rounds_legacy_primary", "gate_v2_legacy_primary",
|
||||||
),
|
),
|
||||||
default=None,
|
default=None,
|
||||||
help="Research-only S/R detector/gate arm.",
|
help="Research-only S/R detector/gate arm.",
|
||||||
|
|||||||
@@ -17,17 +17,12 @@ RUNNER = ROOT / "scripts" / "run_backtest_snapshot.py"
|
|||||||
COMPARE = ROOT / "scripts" / "compare_sr_variants.py"
|
COMPARE = ROOT / "scripts" / "compare_sr_variants.py"
|
||||||
TRAINING_ARMS = (
|
TRAINING_ARMS = (
|
||||||
"production_control",
|
"production_control",
|
||||||
"rr_aligned_control",
|
"rewrite_legacy_primary",
|
||||||
"rewrite",
|
"soft_zones_legacy_primary",
|
||||||
"soft_zones",
|
"confirmed_rounds_legacy_primary",
|
||||||
"confirmed_rounds",
|
"gate_v2_legacy_primary",
|
||||||
"gate_v2",
|
|
||||||
)
|
|
||||||
# confirmed_rounds failed the post-2024 validation decisively and must not be
|
|
||||||
# selected again merely because a corrected training curve looks attractive.
|
|
||||||
LOCKABLE_ARMS = tuple(
|
|
||||||
arm for arm in TRAINING_ARMS[1:] if arm != "confirmed_rounds"
|
|
||||||
)
|
)
|
||||||
|
LOCKABLE_ARMS = TRAINING_ARMS[1:]
|
||||||
|
|
||||||
|
|
||||||
def _add_common(parser: argparse.ArgumentParser) -> None:
|
def _add_common(parser: argparse.ArgumentParser) -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user