{"record":{"id":"f0d0c97b15b7ec91","repo":"HKUDS/Vibe-Trading","slug":"exit-threshold-must-be-below-enter-threshold","errorCode":null,"errorMessage":"exit_threshold must be below enter_threshold","messagePattern":"exit_threshold must be below enter_threshold","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"agent/src/api/system_routes.py","lineNumber":344,"sourceCode":"        edge-density series, causally smoothed, and run through a two-threshold\n        hysteresis state machine. Descriptive risk context, not a trading\n        signal. Shares /correlation's rate-limit budget.\n        \"\"\"\n        from backtest.regime import compute_regime_timeline\n\n        if not _correlation_rate_limiter.allow(_client_key(request)):\n            raise HTTPException(\n                status_code=status.HTTP_429_TOO_MANY_REQUESTS,\n                detail=\"Rate limit exceeded, try again later\",\n            )\n\n        code_list = [c.strip() for c in codes.split(\",\") if c.strip()]\n        if len(code_list) < 2:\n            raise HTTPException(status_code=400, detail=\"At least 2 asset codes required\")\n        if len(code_list) > 20:\n            raise HTTPException(status_code=400, detail=\"Maximum 20 assets per request\")\n        if exit_threshold >= enter_threshold:\n            raise HTTPException(status_code=400, detail=\"exit_threshold must be below enter_threshold\")\n\n        try:\n            return compute_regime_timeline(\n                codes=code_list,\n                days=days,\n                corr_window=corr_window,\n                edge_threshold=edge_threshold,\n                smooth_window=smooth_window,\n                enter_threshold=enter_threshold,\n                exit_threshold=exit_threshold,\n            )\n        except ValueError as exc:\n            raise HTTPException(status_code=400, detail=str(exc))\n        except Exception:\n            logger.exception(\"Regime timeline computation failed for codes=%s\", code_list)\n            raise HTTPException(status_code=500, detail=\"Regime timeline computation failed\")\n\n    @app.post(\"/system/shutdown\")","sourceCodeStart":326,"sourceCodeEnd":362,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/api/system_routes.py#L326-L362","documentation":"Hysteresis-based regime detection requires an exit threshold strictly below the enter threshold; otherwise enter/exit bands would overlap or invert. The endpoint rejects exit_threshold >= enter_threshold with 400.","triggerScenarios":"GET /system/correlation-regime with enter_threshold=0.6&exit_threshold=0.6 or enter_threshold=0.5&exit_threshold=0.7 (defaults or explicit params).","commonSituations":"Clients omitting one threshold so defaults clash, swapping the two parameter names, or scaling thresholds (e.g. 0-100 vs 0-1) inconsistently.","solutions":["Set exit_threshold below enter_threshold, e.g. enter=0.7 exit=0.5","Check parameter order/naming when constructing the query string","Confirm both thresholds use the same scale (0-1 fractions)"],"exampleFix":"# before\nparams = {'enter_threshold': 0.6, 'exit_threshold': 0.6}\n# after\nparams = {'enter_threshold': 0.7, 'exit_threshold': 0.5}","handlingStrategy":"validation","validationCode":"assert enter_threshold > exit_threshold, 'exit_threshold must be below enter_threshold'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate threshold ordering client-side","Keep both thresholds on the same 0-1 scale"],"tags":["validation","thresholds","hysteresis","api"],"backgroundTag":"invalid-parameter-constraint","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}