{"record":{"id":"ec0f6ac28428a397","repo":"QuantConnect/Lean","slug":"maximumsharperatioportfoliooptimizer-portfolio-var","errorCode":null,"errorMessage":"MaximumSharpeRatioPortfolioOptimizer.portfolio_variance: Volatility cannot be zero. Weights: {weights}","messagePattern":"MaximumSharpeRatioPortfolioOptimizer\\.portfolio_variance: Volatility cannot be zero\\. Weights: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Algorithm.Framework/Portfolio/MaximumSharpeRatioPortfolioOptimizer.py","lineNumber":86,"sourceCode":"            {'type': 'eq', 'fun': lambda weights: self.get_budget_constraint(weights)}]\n\n        opt = minimize(lambda weights: -expected_returns.dot(weights) / np.sqrt(self.portfolio_variance(weights, covariance)),   # Objective function: −Sharpe ratio\n                       x0,                                                        # Initial guess\n                       bounds = self.get_boundary_conditions(size),               # Bounds for variables: lw ≤ w ≤ up\n                       constraints = constraints,                                 # Constraints definition\n                       method='SLSQP')        # Optimization method:  Sequential Least SQuares Programming\n\n        return opt['x'] if opt['success'] else x0\n\n    def portfolio_variance(self, weights, covariance):\n        '''Computes the portfolio variance\n        Args:\n            weighs: Portfolio weights\n            covariance: Covariance matrix of historical returns'''\n        variance = np.dot(weights.T, np.dot(covariance, weights))\n        if variance == 0 and np.any(weights):\n            # variance can't be zero, with non zero weights\n            raise ValueError(f'MaximumSharpeRatioPortfolioOptimizer.portfolio_variance: Volatility cannot be zero. Weights: {weights}')\n        return variance\n\n    def get_boundary_conditions(self, size):\n        '''Creates the boundary condition for the portfolio weights'''\n        return tuple((self.minimum_weight, self.maximum_weight) for x in range(size))\n\n    def get_budget_constraint(self, weights):\n        '''Defines a budget constraint: the sum of the weights equals unity'''\n        return np.sum(weights) - 1\n","sourceCodeStart":68,"sourceCodeEnd":96,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.Framework/Portfolio/MaximumSharpeRatioPortfolioOptimizer.py#L68-L96","documentation":"MaximumSharpeRatioPortfolioOptimizer (Python) computes portfolio variance as wᵀ·Σ·w and uses it as a scipy SLSQP constraint. It raises ValueError when variance is exactly 0 but at least one weight is non-zero, because a non-zero allocation can never have zero volatility with a valid covariance matrix — a zero result means the covariance matrix is degenerate.","triggerScenarios":"portfolio_variance() is called by the optimizer with a weights vector and a covariance matrix where np.dot(weights.T, np.dot(covariance, weights)) == 0 while np.any(weights) is true. Happens when the covariance matrix is all-zeros (flat/constant returns) or rank-deficient.","commonSituations":"Lookback/history window too short, securities with no price movement (constant closes), weekend/holiday flat data, duplicated symbols, or a History() call that returned empty rows so the covariance collapsed to zeros.","solutions":["Increase the optimizer's lookback/period so the covariance matrix has enough non-flat return samples.","Before optimizing, verify each symbol actually has price variation in the history window; drop flat or illiquid symbols.","Confirm History() returned data (check the DataFrame is non-empty and not all-NaN) before feeding it to the optimizer.","If some assets legitimately have near-zero volatility, raise the optimizer's minimum_weight or exclude them from the universe."],"exampleFix":"# before\nvariance = np.dot(weights.T, np.dot(covariance, weights))\nif variance == 0 and np.any(weights):\n    raise ValueError(...)\n\n# guard upstream: skip optimization when covariance is degenerate\nif not np.any(np.diag(covariance)):\n    algorithm.Debug('Skipping Sharpe optimization: zero covariance')\n    return x0  # fall back to equal/fallback weights","handlingStrategy":"validation","validationCode":"import numpy as np\n\ndef safe_optimize(optimizer, weights, covariance, fallback):\n    diag = np.diag(covariance)\n    if covariance.size == 0 or not np.any(diag) or np.any(np.isnan(covariance)):\n        return fallback  # e.g., equal weights\n    return optimizer.optimize(weights, covariance)","typeGuard":"def has_real_variance(covariance: np.ndarray) -> bool:\n    return covariance.size > 0 and np.any(np.diag(covariance) > 0) and np.all(np.isfinite(covariance))","tryCatchPattern":null,"preventionTips":["Always pull a sufficiently long History() window for every symbol before computing covariance.","Drop symbols whose return standard deviation is zero before forming the covariance matrix.","Check that History() returned non-empty, finite data — never feed an all-zero covariance to the optimizer."],"tags":["portfolio-optimizer","numpy","scipy","covariance"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}