Require aligned action for qualified setups
This commit is contained in:
@@ -313,7 +313,8 @@ def _acand(
|
||||
) -> dict:
|
||||
"""Ablation candidate: meets_core mirrors the default floors (min_rr 1.2,
|
||||
min_confidence 55, exclude_neutral on)."""
|
||||
meets = rr >= 1.2 and conf >= 55.0 and action != "NEUTRAL"
|
||||
action_dir = "long" if action.startswith("LONG") else "short" if action.startswith("SHORT") else "neutral"
|
||||
meets = rr >= 1.2 and conf >= 55.0 and action_dir != "neutral" and action_dir == direction
|
||||
return {
|
||||
"rr": rr,
|
||||
"confidence": conf,
|
||||
@@ -347,7 +348,7 @@ class TestGateAblation:
|
||||
_acand(rr=1.0), # fails R:R floor
|
||||
_acand(action="NEUTRAL"), # fails NEUTRAL exclusion
|
||||
_acand(mp=50.0), # fails the momentum cutoff
|
||||
_acand(direction="short", mp=95.0), # short — gated out
|
||||
_acand(direction="short", action="SHORT_MODERATE", mp=95.0), # short — gated out
|
||||
]
|
||||
rows = {r["variant"]: r for r in bt._gate_ablation(cands, self.ACTIVATION, 80.0)}
|
||||
assert rows["all_floors"]["total"] == 1
|
||||
@@ -364,7 +365,7 @@ class TestGateAblation:
|
||||
|
||||
def test_threshold_zero_disables_momentum_gate(self):
|
||||
# Floors only: the short and the low-momentum long both pass all_floors.
|
||||
cands = [_acand(mp=50.0), _acand(direction="short", mp=None)]
|
||||
cands = [_acand(mp=50.0), _acand(direction="short", action="SHORT_MODERATE", mp=None)]
|
||||
rows = {r["variant"]: r for r in bt._gate_ablation(cands, self.ACTIVATION, 0.0)}
|
||||
assert rows["all_floors"]["total"] == 2
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ STRICT_GATE = {
|
||||
|
||||
def _setup(**kwargs):
|
||||
base = dict(
|
||||
direction="long",
|
||||
rr_ratio=3.0,
|
||||
confidence_score=80.0,
|
||||
recommended_action="LONG_HIGH",
|
||||
@@ -124,6 +125,15 @@ class TestExcludeNeutral:
|
||||
def test_directional_passes_when_on(self):
|
||||
assert setup_qualifies(_setup(recommended_action="LONG_MODERATE"), NEUTRAL_GATE) is True
|
||||
|
||||
def test_opposing_short_action_fails_for_long_setup(self):
|
||||
assert setup_qualifies(_setup(direction="long", recommended_action="SHORT_MODERATE"), NEUTRAL_GATE) is False
|
||||
|
||||
def test_matching_short_action_still_fails_long_only_momentum_gate(self):
|
||||
assert setup_qualifies(
|
||||
_setup(direction="short", recommended_action="SHORT_MODERATE", momentum_percentile=95.0),
|
||||
{**NEUTRAL_GATE, "min_momentum_percentile": 80.0},
|
||||
) is False
|
||||
|
||||
def test_neutral_allowed_when_off(self):
|
||||
# Flag absent from the config → NEUTRAL still qualifies (backward compatible).
|
||||
assert setup_qualifies(_setup(recommended_action="NEUTRAL"), DEFAULT_GATE) is True
|
||||
|
||||
Reference in New Issue
Block a user