Activation gate: primary target probability floor (>= 20%)
A qualified setup's primary target must now clear MIN_TARGET_PROBABILITY
(20%), shared with the primary-selection floor in recommendation_service
and mirrored in the frontend gate. Closes the read-time hole where a
stale pre-c7a198b row starring a far lottery target (probability pinned
at the 3% clamp floor, R:R inflated by the same distance) qualified
forever: the scanner emits no replacement row and live R:R never decays.
A/B backtest vs c7a198b baseline (same July-3 snapshot): 7 of 1096
qualified setups removed; qualified net avg R 0.202 -> 0.207, hold
Sharpe 2.00 -> 2.02, CAGR +48.8% -> +49.6%, max DD unchanged at -15.8%.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@ from app.models.settings import SystemSetting
|
||||
from app.models.sr_level import SRLevel
|
||||
from app.models.ticker import Ticker
|
||||
from app.models.trade_setup import TradeSetup
|
||||
from app.services.qualification import MIN_TARGET_PROBABILITY
|
||||
from app.services.sr_service import cluster_sr_zones
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -575,10 +576,10 @@ def build_recommendation_snapshot(
|
||||
|
||||
|
||||
PRIMARY_TARGET_MIN_RR = 1.5
|
||||
# Below this the target is a lottery ticket: under the two-barrier model a
|
||||
# fair-race 1.5:1 target sits near ~34% before drift adjustments, so 20% only
|
||||
# excludes targets the model itself considers long shots.
|
||||
PRIMARY_TARGET_MIN_PROBABILITY = 20.0
|
||||
# Below this the target is a lottery ticket. Shared with the activation gate
|
||||
# (qualification.MIN_TARGET_PROBABILITY) so the primary selection and the gate
|
||||
# agree on what counts as a probability-backed target.
|
||||
PRIMARY_TARGET_MIN_PROBABILITY = MIN_TARGET_PROBABILITY
|
||||
|
||||
|
||||
def _select_primary_target(
|
||||
|
||||
Reference in New Issue
Block a user