{"record":{"id":"1193bb74b56a496b","repo":"QuantConnect/Lean","slug":"expected-3-liquidation-events-found-self-liquida","errorCode":null,"errorMessage":"Expected 3 liquidation events, found {self.liquidated}","messagePattern":"Expected 3 liquidation events, found (.+?)","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"Algorithm.Python/FuturesAndFuturesOptionsExpiryTimeAndLiquidationRegressionAlgorithm.py","lineNumber":102,"sourceCode":"        self.liquidated += 1\n        if order_event.symbol.security_type == SecurityType.FUTURE_OPTION and self.expected_liquidation_time != self.time:\n            raise AssertionError(f\"Expected to liquidate option {order_event.symbol} at {self.expected_liquidation_time}, instead liquidated at {self.time}\")\n\n        if order_event.symbol.security_type == SecurityType.FUTURE and \\\n            (self.expected_liquidation_time - timedelta(minutes=1)) != self.time and \\\n            self.expected_liquidation_time != self.time:\n\n            raise AssertionError(f\"Expected to liquidate future {order_event.symbol} at {self.expected_liquidation_time} (+1 minute), instead liquidated at {self.time}\")\n\n    def on_end_of_algorithm(self):\n        if not self.invested:\n            raise AssertionError(\"Never invested in ES futures and FOPs\")\n\n        if self.delistings_received != 4:\n            raise AssertionError(f\"Expected 4 delisting events received, found: {self.delistings_received}\")\n\n        if self.liquidated != 2:\n            raise AssertionError(f\"Expected 3 liquidation events, found {self.liquidated}\")\n","sourceCodeStart":84,"sourceCodeEnd":103,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.Python/FuturesAndFuturesOptionsExpiryTimeAndLiquidationRegressionAlgorithm.py#L84-L103","documentation":"Asserts self.liquidated == 2 (one future liquidation + one FOP exercise). NOTE: the message text says 'Expected 3 liquidation events' but the code checks '!= 2' — the message is wrong; the intended count is 2. Failing means too few or too many SELL/FILLED order events fired.","triggerScenarios":"Extra liquidation events from an unexpected underlying future sale; missing the FOP exercise event; duplicate fills inflating the counter.","commonSituations":"Engine changes introducing an additional auto-liquidation (the very case the comment says should NOT happen); data changes causing the FOP not to exercise; order-event duplication after a refactor.","solutions":["Log each order_event that increments self.liquidated (symbol + security_type) to see what is extra/missing.","If an extra underlying-future liquidation appears, investigate why the breakeven assumption broke.","Trust the code (== 2) over the message text ('3') when reconciling.","Update the count if engine behaviour intentionally changed, and fix the misleading message."],"exampleFix":"// before\nif self.liquidated != 2:\n    raise AssertionError(f\"Expected 3 liquidation events, found {self.liquidated}\")\n// after - correct the message\nif self.liquidated != 2:\n    raise AssertionError(f\"Expected 2 liquidation events, found {self.liquidated}\")","handlingStrategy":"validation","validationCode":"# Track liquidation events with detail\nif order_event.direction == OrderDirection.SELL and order_event.status == OrderStatus.FILLED:\n    self.liquidated += 1\n    self.debug(f\"Liquidation #{self.liquidated}: {order_event.symbol.security_type} {order_event.symbol}\")","typeGuard":"def is_liquidation_fill(order_event) -> bool:\n    return order_event.direction == OrderDirection.SELL and order_event.status == OrderStatus.FILLED","tryCatchPattern":null,"preventionTips":["Trust the code (== 2) over the message text ('3').","Log each liquidation's security_type to spot unexpected underlying sales.","Investigate any extra FUTURE liquidation — the comment says it should not happen.","Fix the misleading message when touching this assertion."],"tags":["quantconnect","futures","future-options","liquidation","event-count","regression-test"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}