{"record":{"id":"bbb303d84563006c","repo":"QuantConnect/Lean","slug":"tradestrategy-method-is-not-implemented","errorCode":null,"errorMessage":"TradeStrategy method is not implemented","messagePattern":"TradeStrategy method is not implemented","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"Algorithm.Python/OptionStrategyFactoryMethodsBaseAlgorithm.py","lineNumber":69,"sourceCode":"            self.liquidate_strategy()\n\n            # We can quit now, no more testing required\n            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":51,"sourceCodeEnd":76,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.Python/OptionStrategyFactoryMethodsBaseAlgorithm.py#L51-L76","documentation":"trade_strategy(chain, option_symbol) is the abstract entry point on OptionStrategyFactoryMethodsBaseAlgorithm that on_data calls to actually build and submit the option strategy orders. The base raises NotImplementedError because it has no concrete strategy to trade; a subclass must supply the OptionStrategies combo and the Buy call. Hitting it means the algorithm tried to trade through the unimplemented base method.","triggerScenarios":"on_data receives a non-None option chain while self.portfolio.invested is False and calls self.trade_strategy(...) on an instance whose class did not override trade_strategy. Happens when the base class is run or a subclass omits the override.","commonSituations":"Running the base class directly; creating a new subclass and forgetting to implement trade_strategy; renaming the base method without updating subclasses.","solutions":["Implement trade_strategy in your subclass: build the strategy via OptionStrategies and call self.buy(strategy, quantity).","Run a concrete subclass, not the base.","Use @abstractmethod so missing overrides fail at construction."],"exampleFix":"# before: base raises NotImplementedError\n# after\ndef trade_strategy(self, chain, option_symbol):\n    strategy = OptionStrategies.CoveredCall(option_symbol)\n    self.buy(strategy, 1)","handlingStrategy":"validation","validationCode":"# Detect an unoverridden template method before trading\nif self.trade_strategy.__func__ is OptionStrategyFactoryMethodsBaseAlgorithm.trade_strategy:\n    raise NotImplementedError('Subclass must override trade_strategy()')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use @abstractmethod to surface missing overrides at instantiation.","Always implement trade_strategy in subclasses.","Run a concrete subclass, not the base."],"tags":["options","template-method","not-implemented","quantconnect","option-strategy","inheritance"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}