{"record":{"id":"956cf64b101c6773","repo":"QuantConnect/Lean","slug":"time-unexpected-symbol-changed-event-changedeve-956cf6","errorCode":null,"errorMessage":"{Time} unexpected symbol changed event {changedEvent}!","messagePattern":"(.+?) unexpected symbol changed event (.+?)!","errorType":"exception","errorClass":"RegressionTestException","httpStatus":null,"severity":"warning","filePath":"Algorithm.CSharp/BasicTemplateFuturesWithExtendedMarketAlgorithm.cs","lineNumber":82,"sourceCode":"            var benchmark = AddEquity(\"SPY\");\n            SetBenchmark(benchmark.Symbol);\n\n            var seeder = new FuncSecuritySeeder(GetLastKnownPrices);\n            SetSecurityInitializer(security => seeder.SeedSecurity(security));\n        }\n\n        /// <summary>\n        /// Event - v3.0 DATA EVENT HANDLER: (Pattern) Basic template for user to override for receiving all subscription data in a single event\n        /// </summary>\n        /// <param name=\"slice\">The current slice of data keyed by symbol string</param>\n        public override void OnData(Slice slice)\n        {\n            foreach (var changedEvent in slice.SymbolChangedEvents.Values)\n            {\n                Debug($\"{Time} - SymbolChanged event: {changedEvent}\");\n                if (Time.TimeOfDay != TimeSpan.Zero)\n                {\n                    throw new RegressionTestException($\"{Time} unexpected symbol changed event {changedEvent}!\");\n                }\n            }\n\n            if (!Portfolio.Invested)\n            {\n                foreach(var chain in slice.FutureChains)\n                {\n                    // find the front contract expiring no earlier than in 90 days\n                    var contract = (\n                        from futuresContract in chain.Value.OrderBy(x => x.Expiry)\n                        where futuresContract.Expiry > Time.Date.AddDays(90)\n                        select futuresContract\n                    ).FirstOrDefault();\n\n                    // if found, trade it\n                    if (contract != null)\n                    {\n                        _contractSymbol = contract.Symbol;","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.CSharp/BasicTemplateFuturesWithExtendedMarketAlgorithm.cs#L64-L100","documentation":"The extended-market futures regression asserts SymbolChangedEvents (rollovers) occur only at midnight (Time.TimeOfDay == TimeSpan.Zero). Because this algorithm trades extended market hours, an off-midnight mapping is especially suspect — it suggests the rollover leaked into the extended session rather than the daily boundary.","triggerScenarios":"A SymbolChangedEvent arrives in OnData while Time.TimeOfDay != TimeSpan.Zero in an extended-hours futures algorithm — the continuous contract remapped during the extended or regular session instead of midnight.","commonSituations":"Extended-hours data shifted the mapping timestamp; DataMappingMode timing changed; an extended-market subscription caused the slice Time to read an intraday value at rollover; engine version altered mapping emission for extended sessions.","solutions":["Confirm extended-hours subscription does not shift the rollover slice Time off midnight.","Verify DataMappingMode maps at the daily boundary for the extended feed.","If extended-session rollovers are legitimate for your feed, relax the midnight assertion.","Ensure the continuous-contract mapping clock aligns with the intended session calendar."],"exampleFix":"// before\nif (Time.TimeOfDay != TimeSpan.Zero) { throw ...; }\n\n// after: log and investigate extended-session rollovers\nif (Time.TimeOfDay != TimeSpan.Zero) { Log($\"Extended-session rollover at {Time}: {changedEvent}\"); }","handlingStrategy":"validation","validationCode":"foreach (var changedEvent in slice.SymbolChangedEvents.Values)\n{\n    if (Time.TimeOfDay != TimeSpan.Zero)\n    {\n        Log($\"{Time} - Extended-session rollover: {changedEvent}. Verify feed/mapping.\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Confirm extended-hours subscription does not shift rollover Time off midnight.","Verify DataMappingMode maps at the daily boundary.","Pin Lean version for deterministic extended-session rollover timing."],"tags":["futures","continuous-contract","symbol-mapping","regression-test","extended-market","timing"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}