{"record":{"id":"17cf9749ec6d38e9","repo":"QuantConnect/Lean","slug":"expiry-warning-with-time-delisting-time-but-is-e","errorCode":null,"errorMessage":"Expiry warning with time {delisting.time} but is expected to be {self.expected_expiry_warning_time}","messagePattern":"Expiry warning with time (.+?) but is expected to be (.+?)","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"Algorithm.Python/FuturesAndFuturesOptionsExpiryTimeAndLiquidationRegressionAlgorithm.py","lineNumber":57,"sourceCode":"\n        es_option = Symbol.create_option(\n            es,\n            Market.CME,\n            OptionStyle.AMERICAN,\n            OptionRight.PUT,\n            3400.0,\n            datetime(2020, 6, 19)\n        )\n\n        self.es_future = self.add_future_contract(es, Resolution.MINUTE).symbol\n        self.es_future_option = self.add_future_option_contract(es_option, Resolution.MINUTE).symbol\n\n    def on_data(self, data: Slice):\n        for delisting in data.delistings.values():\n            self.delistings_received += 1\n\n            if delisting.type == DelistingType.WARNING and delisting.time != self.expected_expiry_warning_time:\n                raise AssertionError(f\"Expiry warning with time {delisting.time} but is expected to be {self.expected_expiry_warning_time}\")\n\n            if delisting.type == DelistingType.WARNING and delisting.time != datetime(self.time.year, self.time.month, self.time.day):\n                raise AssertionError(f\"Delisting warning received at an unexpected date: {self.time} - expected {delisting.time}\")\n\n            if delisting.type == DelistingType.DELISTED and delisting.time != self.expected_expiry_delisting_time:\n                raise AssertionError(f\"Delisting occurred at unexpected time: {delisting.time} - expected: {self.expected_expiry_delisting_time}\")\n\n            if delisting.type == DelistingType.DELISTED and delisting.time != datetime(self.time.year, self.time.month, self.time.day):\n                raise AssertionError(f\"Delisting notice received at an unexpected date: {self.time} - expected {delisting.time}\")\n\n        if not self.invested and \\\n            (self.es_future in data.bars or self.es_future in data.quote_bars) and \\\n            (self.es_future_option in data.bars or self.es_future_option in data.quote_bars):\n\n            self.invested = True\n\n            self.market_order(self.es_future, 1)\n            self.market_order(self.es_future_option, 1)","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.Python/FuturesAndFuturesOptionsExpiryTimeAndLiquidationRegressionAlgorithm.py#L39-L75","documentation":"Delisting-timing assertion for a future/FOP expiry regression. When a DelistingType.WARNING event arrives, the test requires delisting.time to equal the hardcoded expected_expiry_warning_time (datetime(2020, 6, 19)). Any mismatch aborts, validating the engine emits the warning on the contract's last trading day.","triggerScenarios":"Engine emitting the delisting warning on a different date (e.g. the day before or after expiry); delisting.time carrying an unexpected time component; data file expiry metadata disagreeing with the hardcoded expectation.","commonSituations":"Changes to delisting-warning emission logic in Lean; timezone shifts so delisting.time resolves to an adjacent day; data refreshes with corrected expiry dates that no longer match 2020-06-19.","solutions":["Print delisting.time and self.expected_expiry_warning_time to see the exact delta.","Verify the data file's expiry metadata for the ES / ES-option contract.","Update expected_expiry_warning_time if the engine's warning-day semantics changed on purpose.","Check whether delisting.time now includes a time-of-day component the comparison should normalize."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# Validate warning time against expectation before raising\nif delisting.type == DelistingType.WARNING:\n    if delisting.time != self.expected_expiry_warning_time:\n        self.debug(f\"Warning time {delisting.time} != expected {self.expected_expiry_warning_time}\")","typeGuard":"def warning_time_matches(delisting, expected: datetime) -> bool:\n    return delisting.type == DelistingType.WARNING and delisting.time == expected","tryCatchPattern":null,"preventionTips":["Keep expected_expiry_warning_time in sync with the data's expiry metadata.","Strip time-of-day if only the date is meaningful.","Log raw delisting.time and expected values on mismatch.","Re-baseline expectations after engine delisting-logic changes."],"tags":["quantconnect","futures","future-options","delisting","expiry","regression-test"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}