math-backend / docs /RELAXATION_CASCADE.md
engineportf's picture
Upload folder using huggingface_hub
558db1e verified
|
Raw
History Blame Contribute Delete
3.28 kB

Constraint Relaxation Cascade

The Quantitative Portfolio Engine implements a robust 7-stage constraint relaxation cascade. This exists because strict convex optimization models (like CVXPY) frequently encounter feasibility limits (infeasible or optimal_inaccurate states) when processing dense covariance matrices with tight turnover, sector, and minimum weight constraints.

When the primary formulation pushes solver limits or hits numerical precision walls, the engine sequentially relaxes constraints to find the nearest feasible mathematical solution, rather than failing abruptly.

The 7-Stage Cascade

Stage 1: Strict Formulation

  • Objective: Tries to solve the exact formulation provided by the user constraints.
  • Constraints Active: Minimum and maximum single asset weights, sector concentration limits, total turnover caps, and target Beta.

Stage 2: Beta Range Expansion

  • Relaxation: The target market beta equality constraint is softened to an inequality range (e.g., Target Beta ± 0.1).
  • Reason: Perfect beta matching is often mathematically impossible when paired with tight turnover limits.

Stage 3: Turnover Relaxation

  • Relaxation: The max_turnover constraint is completely disabled.
  • Reason: In highly volatile regimes, the expected returns might shift drastically. Preventing the solver from trading (turnover cap) makes it impossible to reach the efficient frontier, causing infeasibility.

Stage 4: Sector Limit Expansion

  • Relaxation: The sector_limit constraint is disabled.
  • Reason: When correlations cluster heavily within a single sector (e.g., Tech during a rally), the optimizer wants to overweight that sector to achieve the target return/Sharpe. Removing this limit prevents artificial underperformance clipping.

Stage 5: Zero Floor (No Shorts)

  • Relaxation: single_asset_min is strictly floored at 0.0. Shorting is completely disabled.
  • Reason: Leverage and short-borrow cost parameters can create unstable quadratic objective spaces (non-PSD covariance interactions). Forcing a long-only constraint space guarantees a more stable OSQP projection.

Stage 6: Unconstrained Max Weight

  • Relaxation: single_asset_max is pushed to 1.0 (100%).
  • Reason: At this point, the solver is struggling to find any combination of assets that satisfies the risk constraints. Allowing a 100% allocation into the safest asset (like CASH or TLT) gives the solver an "escape hatch".

Stage 7: Cash Fallback

  • Relaxation: If all else fails, the engine abandons the Markowitz optimization entirely.
  • Action: It assigns 100% of the portfolio to the risk-free asset or cash proxy (e.g., CASH).
  • Reason: A mathematical failure in the convex space implies the risk regime is fundamentally broken or the input covariance matrix is irrecoverably singular. Protecting capital via a 100% cash allocation is the safest programmatic fallback.

Solver Notes

Even when passing feasibility checks, solvers like OSQP or ECOS may occasionally return OPTIMAL_INACCURATE. This is normal when dealing with near-collinear assets that leave tiny negative eigenvalues (e.g., 4e-7). The cascade logs these occurrences and proceeds with the projected PSD matrix.