{"record":{"id":"0e3de66443516f8c","repo":"QuantConnect/Lean","slug":"index-is-not-tradable-0e3de6","errorCode":null,"errorMessage":"Index is not tradable.","messagePattern":"Index is not tradable\\.","errorType":"exception","errorClass":"RegressionTestException","httpStatus":null,"severity":"error","filePath":"Algorithm.CSharp/BasicTemplateIndexOptionsAlgorithm.cs","lineNumber":106,"sourceCode":"                    if (_emaFast > _emaSlow && contract.Right == OptionRight.Call)\n                    {\n                        Liquidate(InvertOption(contract.Symbol));\n                        MarketOrder(contract.Symbol, 1);\n                    }\n                    else if (_emaFast < _emaSlow && contract.Right == OptionRight.Put)\n                    {\n                        Liquidate(InvertOption(contract.Symbol));\n                        MarketOrder(contract.Symbol, 1);\n                    }\n                }\n            }\n        }\n\n        public override void OnEndOfAlgorithm()\n        {\n            if (Portfolio[_spx].TotalSaleVolume > 0)\n            {\n                throw new RegressionTestException(\"Index is not tradable.\");\n            }\n            if (Portfolio.TotalSaleVolume == 0)\n            {\n                throw new RegressionTestException(\"Trade volume should be greater than zero by the end of this algorithm\");\n            }\n            AssertIndicators();\n        }\n\n        public Symbol InvertOption(Symbol symbol)\n        {\n            return QuantConnect.Symbol.CreateOption(\n                symbol.Underlying,\n                symbol.ID.Market,\n                symbol.ID.OptionStyle,\n                symbol.ID.OptionRight == OptionRight.Call ? OptionRight.Put : OptionRight.Call,\n                symbol.ID.StrikePrice,\n                symbol.ID.Date);\n        }","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.CSharp/BasicTemplateIndexOptionsAlgorithm.cs#L88-L124","documentation":"Identical assertion to error 21 but in BasicTemplateIndexOptionsAlgorithm. Thrown when Portfolio[_spx].TotalSaleVolume > 0, meaning the engine filled orders on the SPX index itself. Index symbols must remain non-tradable — only their options should generate fills.","triggerScenarios":"The OnData logic calls MarketOrder on the _spx index symbol instead of a contract symbol, the engine's IsTradable flag for index securities was reset, or a Liquidate() call inadvertently targets the index.","commonSituations":"Code refactoring that passes _spx to MarketOrder instead of contract.Symbol, brokerage model changes affecting index tradability, or engine-level security initialization bugs.","solutions":["Audit all order method calls (MarketOrder, LimitOrder, Liquidate, SetHoldings) to confirm they use option contract symbols, not _spx.","Log Securities[_spx].IsTradable after Initialize to verify it is false.","Check for InvertOption() misuse — ensure it returns option symbols, not the underlying index.","Review the IndexSecurity/SecurityService code path for IsTradable default assignment."],"exampleFix":"// before — Liquidate(_spx) is called somewhere\nLiquidate(_spx);\n\n// after — liquidate specific option positions\nLiquidate(contract.Symbol);","handlingStrategy":"validation","validationCode":"// Verify index is non-tradable before running\nif (Securities[_spx].IsTradable)\n{\n    Log($\"WARNING: {_spx} is tradable — index should not be\");\n}\n// Verify no order calls reference _spx\nforeach (var kvp in Securities)\n{\n    if (kvp.Key == _spx && kvp.Value.Holdings.Quantity != 0)\n        Log($\"Unexpected position on index {_spx}: {kvp.Value.Holdings.Quantity}\");\n}","typeGuard":"bool IsTradableSecurity(Symbol sym) =>\n    Securities[sym].IsTradable && Securities[sym].Type != SecurityType.Index;","tryCatchPattern":null,"preventionTips":["Use only option contract symbols (from chain.Contracts) for order calls.","Verify InvertOption() always returns option symbols, never the underlying.","Log Securities[_spx].IsTradable after Initialize.","Add unit tests that assert index symbols cannot receive fills."],"tags":["quantconnect","index","tradability","options","regression-test","portfolio"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}