{"record":{"id":"4ef1992f160e3c1d","repo":"QuantConnect/Lean","slug":"assertstrategypositiongroup-method-is-not-implemen","errorCode":null,"errorMessage":"AssertStrategyPositionGroup method is not implemented","messagePattern":"AssertStrategyPositionGroup method is not implemented","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"Algorithm.Python/OptionStrategyFactoryMethodsBaseAlgorithm.py","lineNumber":72,"sourceCode":"            self.quit()\n\n    def on_end_of_algorithm(self):\n        if self.portfolio.invested:\n            raise AssertionError(\"Expected no holdings at end of algorithm\")\n\n        orders_count = len(list(self.transactions.get_orders(lambda order: order.status == OrderStatus.FILLED)))\n        if orders_count != self.expected_orders_count():\n            raise AssertionError(f\"Expected {self.expected_orders_count()} orders to have been submitted and filled, \"\n                            f\"half for buying the strategy and the other half for the liquidation. Actual {orders_count}\")\n\n    def expected_orders_count(self) -> int:\n        raise NotImplementedError(\"ExpectedOrdersCount method is not implemented\")\n\n    def trade_strategy(self, chain: OptionChain, option_symbol: Symbol) -> None:\n        raise NotImplementedError(\"TradeStrategy method is not implemented\")\n\n    def assert_strategy_position_group(self, position_group: IPositionGroup, option_symbol: Symbol) -> None:\n        raise NotImplementedError(\"AssertStrategyPositionGroup method is not implemented\")\n\n    def liquidate_strategy(self) -> None:\n        raise NotImplementedError(\"LiquidateStrategy method is not implemented\")\n","sourceCodeStart":54,"sourceCodeEnd":76,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.Python/OptionStrategyFactoryMethodsBaseAlgorithm.py#L54-L76","documentation":"assert_strategy_position_group is the abstract verification hook on OptionStrategyFactoryMethodsBaseAlgorithm. After the strategy is invested, on_data calls it so the subclass can assert the position group contains exactly the expected legs (symbols, quantities, right/strike/expiry). The base raises NotImplementedError because the expected legs depend on the concrete strategy; a subclass must define them.","triggerScenarios":"on_data reaches the post-investment verification branch and calls self.assert_strategy_position_group(position_group, self._option_symbol) on an instance whose class did not override the method.","commonSituations":"Running the base class; a new subclass missing the override; refactoring the base signature without updating overrides.","solutions":["Implement assert_strategy_position_group in the subclass to check group positions match the strategy legs.","Run a concrete subclass instead of the base.","Decorate with @abstractmethod to surface the omission earlier."],"exampleFix":"# before: base raises NotImplementedError\n# after\ndef assert_strategy_position_group(self, position_group, option_symbol):\n    positions = list(position_group.positions)\n    assert len(positions) == 2, 'Expected 2 legs in the group'","handlingStrategy":"validation","validationCode":"if self.assert_strategy_position_group.__func__ is OptionStrategyFactoryMethodsBaseAlgorithm.assert_strategy_position_group:\n    raise NotImplementedError('Subclass must override assert_strategy_position_group()')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Decorate abstract template methods with @abstractmethod.","Implement every hook when subclassing the base.","Run concrete subclasses only."],"tags":["options","template-method","not-implemented","quantconnect","option-strategy","inheritance","position-group"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}