feat(risk): add apply_risk_gate to all crypto entrypoints#63
Conversation
Co-Authored-By: Claude <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
Risk gate REJECT/APPROVE paths now carry budgets forward so entrypoint execution-contract tests keep working when concentration limits fire. Co-Authored-By: Claude <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Preserve budgets on reject; pool rotation uses default gate; trend/BTC use 50% cap. Co-Authored-By: Claude <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 757caa828e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return StrategyDecision( | ||
| positions=decision.positions, | ||
| risk_flags=tuple(risk_flags), | ||
| diagnostics={**(decision.diagnostics or {}), "risk_gate": "APPROVE"}, |
There was a problem hiding this comment.
Preserve budgets when approving decisions
When any entrypoint passes the gate with positions, this reconstructs StrategyDecision without carrying over decision.budgets, even though the entrypoints just populated DCA/trend BudgetIntents before calling apply_risk_gate. Approved decisions therefore expose empty or missing budgets, so downstream execution loses the pool amounts while positions still look approved. Carry forward the original budgets when returning the approved decision.
Useful? React with 👍 / 👎.
| if max_single_weight < 1.0: | ||
| for p in positions: | ||
| weight = abs(float(p.target_weight)) | ||
| if weight > max_single_weight: |
There was a problem hiding this comment.
Avoid applying altcoin caps to core BTC allocations
This concentration check is applied to every position, including the core BTCUSDT leg. With the new callers, crypto_live_pool_rotation uses max_single_weight=0.30 while its own get_dynamic_btc_target_ratio() exceeds 30% above about $17.2k equity, and crypto_btc_dca uses 0.50 while the strategy targets up to 65%, so ordinary accounts are converted to empty rejected decisions before execution. Exempt the core BTC role or align these caps with the BTC target range.
Useful? React with 👍 / 👎.
| risk_flags=risk_flags, | ||
| diagnostics=diagnostics, | ||
| ) | ||
| return apply_risk_gate(decision, max_single_weight=0.30) |
There was a problem hiding this comment.
Relax the cap for normal two-asset trend rotations
With the default rotation_top_n=2, crypto_trend_rotation.compute_signals() returns selected rotation weights normalized across the two winners, so at least one selected position is usually 50% or more before any volatility reduction. Passing those normal successful rotations through a 30% single-position cap rejects the entire decision and emits an empty portfolio whenever candidates exist; use a cap compatible with the configured top-N or scale the weights instead of rejecting them.
Useful? React with 👍 / 👎.
| risk_flags=risk_flags, | ||
| diagnostics=diagnostics, | ||
| ) | ||
| return apply_risk_gate(decision) |
There was a problem hiding this comment.
Enforce a concentration limit for the combo entrypoint
This call relies on the default max_single_weight=1.0, so crypto_equity_combo effectively skips the new single-position concentration gate while the other crypto entrypoints set explicit caps. In normal combo runs with only one rotation winner, the trend leg can allocate most of the configured trend sleeve to a single altcoin and still pass, which leaves this entrypoint outside the hard risk control this change is adding.
Useful? React with 👍 / 👎.
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
This comment has been minimized.
This comment has been minimized.
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
This comment has been minimized.
This comment has been minimized.
Co-Authored-By: Claude <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
Summary
apply_risk_gate()in entrypoints/_common.pyTest plan
Made with Cursor