{"record":{"id":"cb81bf5209ea0845","repo":"QuantConnect/Lean","slug":"expected-no-order-events-for-underlying-symbol-se","errorCode":null,"errorMessage":"Expected no order events for underlying Symbol {security.symbol}","messagePattern":"Expected no order events for underlying Symbol (.+?)","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"Algorithm.Python/FutureOptionShortPutOTMExpiryRegressionAlgorithm.py","lineNumber":82,"sourceCode":"            if delisting.type == DelistingType.WARNING:\n                if delisting.time != datetime(2020, 6, 19):\n                    raise AssertionError(f\"Delisting warning issued at unexpected date: {delisting.time}\")\n\n            if delisting.type == DelistingType.DELISTED:\n                if delisting.time != datetime(2020, 6, 20):\n                    raise AssertionError(f\"Delisting happened at unexpected date: {delisting.time}\")\n\n    def on_order_event(self, order_event: OrderEvent):\n        if order_event.status != OrderStatus.FILLED:\n            # There's lots of noise with OnOrderEvent, but we're only interested in fills.\n            return\n\n        if not self.securities.contains_key(order_event.symbol):\n            raise AssertionError(f\"Order event Symbol not found in Securities collection: {order_event.symbol}\")\n\n        security = self.securities[order_event.symbol]\n        if security.symbol == self.es19m20:\n            raise AssertionError(f\"Expected no order events for underlying Symbol {security.symbol}\")\n\n        if security.symbol == self.expected_contract:\n            self.assert_future_option_contract_order(order_event, security)\n\n        else:\n            raise AssertionError(f\"Received order event for unknown Symbol: {order_event.symbol}\")\n\n        self.log(f\"{order_event}\")\n\n    def assert_future_option_contract_order(self, order_event: OrderEvent, option_contract: Security):\n        if order_event.direction == OrderDirection.SELL and option_contract.holdings.quantity != -1:\n            raise AssertionError(f\"No holdings were created for option contract {option_contract.symbol}\")\n\n        if order_event.direction == OrderDirection.BUY and option_contract.holdings.quantity != 0:\n            raise AssertionError(\"Expected no options holdings after closing position\")\n\n        if order_event.is_assignment:\n            raise AssertionError(f\"Assignment was not expected for {order_event.symbol}\")","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.Python/FutureOptionShortPutOTMExpiryRegressionAlgorithm.py#L64-L100","documentation":"FutureOptionShortPutOTMExpiryRegressionAlgorithm.on_order_event asserts that no fill order event arrives for the future underlying symbol (es19m20). The regression shorts an OTM put on the ES future and expects only the option contract to transact; an order event on the underlying itself signals an unintended assignment/exercise of the future.","triggerScenarios":"on_order_event receives a FILLED OrderEvent whose symbol equals self.es19m20 (the underlying future), which the test treats as an error because the underlying should never fill in this OTM-expiry scenario.","commonSituations":"Framework/expiration logic changed so the OTM option got assigned or auto-exercised into a future position; a margin/liquidation event forced an underlying trade; or data changes made the put ITM at expiry triggering assignment.","solutions":["Verify the put is genuinely OTM at expiry in the test data (an ITM put would legitimately assign into the future).","If you changed option assignment/exercise or expiration pipeline code, check whether it now incorrectly exercises OTM options.","Confirm self.es19m20 is the correct expected underlying and that no other symbol aliases to it."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# In on_order_event, ignore the underlying only when truly OTM; otherwise expect assignment\nif order_event.status != OrderStatus.FILLED:\n    return\nif order_event.symbol == self.es19m20 and not self.put_is_it_at_expiry():\n    raise AssertionError(f'Unexpected underlying fill: {order_event}')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When authoring option regression tests, encode the ITM/OTM-at-expiry assumption explicitly and assert the strike vs underlying.","If assignment becomes valid for your scenario, remove/relax the underlying-fill assertion rather than letting it fire."],"tags":["regression-test","future-options","order-events","assignment"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}