remove min_target_probability gate + add chart time-range presets
min_target_probability is gone: it filtered on the probability model the calibration has repeatedly shown to be weak and overconfident, it was redundant with the momentum gate, and as an off-by-default knob it just invited bad tuning. Removed from the backend gate, activation config/schema, the frontend mirror (qualifiesSetup / activationSummary), and ActivationSettings. The probability model stays where it does real work (primary-target selection + display). Charts: with multi-year history the all-bars default was unreadable. Added time-range presets (1M / 3M / 6M / YTD / 1Y / 3Y / 5Y / All), defaulting to 1Y; clicking a preset always re-applies (snaps back after a manual zoom). Y-axis autoscale and wheel-zoom / drag-pan were already there. 339 backend tests pass; frontend build clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -28,7 +28,6 @@ class TestActivationConfig:
|
||||
"min_momentum_percentile": 80.0,
|
||||
"min_rr": 1.2,
|
||||
"min_confidence": 55.0,
|
||||
"min_target_probability": 0.0,
|
||||
"require_high_conviction": False,
|
||||
"exclude_conflicts": False,
|
||||
}
|
||||
@@ -57,12 +56,11 @@ class TestActivationConfig:
|
||||
async def test_conviction_flags_round_trip(self, session: AsyncSession):
|
||||
await update_activation_config(
|
||||
session,
|
||||
{"require_high_conviction": False, "exclude_conflicts": False, "min_target_probability": 45.0},
|
||||
{"require_high_conviction": True, "exclude_conflicts": True},
|
||||
)
|
||||
config = await get_activation_config(session)
|
||||
assert config["require_high_conviction"] is False
|
||||
assert config["exclude_conflicts"] is False
|
||||
assert config["min_target_probability"] == 45.0
|
||||
assert config["require_high_conviction"] is True
|
||||
assert config["exclude_conflicts"] is True
|
||||
|
||||
async def test_rejects_negative_rr(self, session: AsyncSession):
|
||||
with pytest.raises(ValidationError):
|
||||
@@ -71,7 +69,3 @@ class TestActivationConfig:
|
||||
async def test_rejects_out_of_range_confidence(self, session: AsyncSession):
|
||||
with pytest.raises(ValidationError):
|
||||
await update_activation_config(session, {"min_confidence": 120.0})
|
||||
|
||||
async def test_rejects_out_of_range_target_probability(self, session: AsyncSession):
|
||||
with pytest.raises(ValidationError):
|
||||
await update_activation_config(session, {"min_target_probability": 150.0})
|
||||
|
||||
@@ -12,7 +12,6 @@ DEFAULT_GATE = {
|
||||
"min_momentum_percentile": 0.0,
|
||||
"min_rr": 1.2,
|
||||
"min_confidence": 55.0,
|
||||
"min_target_probability": 0.0,
|
||||
"require_high_conviction": False,
|
||||
"exclude_conflicts": False,
|
||||
}
|
||||
@@ -25,7 +24,6 @@ STRICT_GATE = {
|
||||
"min_momentum_percentile": 0.0,
|
||||
"min_rr": 2.0,
|
||||
"min_confidence": 70.0,
|
||||
"min_target_probability": 60.0,
|
||||
"require_high_conviction": True,
|
||||
"exclude_conflicts": True,
|
||||
}
|
||||
@@ -112,9 +110,6 @@ class TestStrictTighteners:
|
||||
s = _setup(risk_level="Medium", targets=[{"probability": 65.0, "is_primary": True}])
|
||||
assert setup_qualifies(s, STRICT_GATE) is False
|
||||
|
||||
def test_low_target_probability_fails(self):
|
||||
assert setup_qualifies(_setup(targets=[{"probability": 40.0, "is_primary": True}]), STRICT_GATE) is False
|
||||
|
||||
|
||||
class TestBestTargetProbability:
|
||||
def test_returns_max(self):
|
||||
|
||||
Reference in New Issue
Block a user