{"record":{"id":"2580a2022f7b9b0d","repo":"ZhuLinsen/daily_stock_analysis","slug":"portfolio-oversell","errorCode":"portfolio_oversell","errorMessage":"Oversell detected for {symbol}{date_hint}: requested={round(requested_quantity, 8)}, available={round(available_quantity, 8)}","messagePattern":"Oversell detected for (.+?)(.+?): requested=(.+?), available=(.+?)","errorType":"validation","errorClass":"PortfolioOversellError","httpStatus":409,"severity":"error","filePath":"src/services/portfolio_service.py","lineNumber":691,"sourceCode":"        market: str,\n        currency: str,\n        trade_date: date,\n        quantity: float,\n        session: Optional[Any] = None,\n    ) -> None:\n        key = (\n            self._normalize_symbol_for_position(symbol),\n            self._normalize_market(market),\n            self._normalize_currency(currency),\n        )\n        available_quantity = self._calculate_available_quantity(\n            account_id=account_id,\n            key=key,\n            as_of_date=trade_date,\n            session=session,\n        )\n        if available_quantity + EPS < quantity:\n            raise PortfolioOversellError(\n                symbol=key[0],\n                trade_date=trade_date,\n                requested_quantity=quantity,\n                available_quantity=available_quantity,\n            )\n\n    def _calculate_available_quantity(\n        self,\n        *,\n        account_id: int,\n        key: Tuple[str, str, str],\n        as_of_date: date,\n        session: Optional[Any] = None,\n    ) -> float:\n        if session is None:\n            trades = self.repo.list_trades(account_id, as_of=as_of_date)\n            corporate_actions = self.repo.list_corporate_actions(account_id, as_of=as_of_date)\n        else:","sourceCodeStart":673,"sourceCodeEnd":709,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/src/services/portfolio_service.py#L673-L709","documentation":"Error \"Oversell detected for {symbol}{date_hint}: requested={round(requested_quantity, 8)}, available={round(available_quantity, 8)}\" thrown in ZhuLinsen/daily_stock_analysis.","triggerScenarios":"Thrown at src/services/portfolio_service.py:691 when the library encounters an invalid state.","commonSituations":"Raised when a sell request exceeds the available quantity for the symbol; occurs when the requested sell amount is larger than the computed holdings, preventing overselling.","solutions":["Reduce the sell quantity to at most the available position.","Check prior trades for the symbol to ensure buys were recorded before sells.","Correct the trade date/order if sells are being applied before their corresponding buys."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}