{"record":{"id":"af4a0259054bbe74","repo":"QuantConnect/Lean","slug":"index-is-not-tradable-af4a02","errorCode":null,"errorMessage":"Index is not tradable.","messagePattern":"Index is not tradable\\.","errorType":"exception","errorClass":"RegressionTestException","httpStatus":null,"severity":"error","filePath":"Algorithm.CSharp/BasicTemplateIndiaIndexAlgorithm.cs","lineNumber":95,"sourceCode":"\n            if (_emaFast > _emaSlow)\n            {\n                if (!Portfolio.Invested)\n                {\n                    var marketTicket = MarketOrder(NiftyETF, 1);\n                }\n            }\n            else\n            {\n                Liquidate();\n            }\n        }\n\n        public override void OnEndOfAlgorithm()\n        {\n            if (Portfolio[Nifty].TotalSaleVolume > 0)\n            {\n                throw new RegressionTestException(\"Index is not tradable.\");\n            }\n        }\n\n        /// <summary>\n        /// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.\n        /// </summary>\n        public virtual bool CanRunLocally { get; } = true;\n\n        /// <summary>\n        /// This is used by the regression test system to indicate which languages this algorithm is written in.\n        /// </summary>\n        public virtual List<Language> Languages { get; } = new() { Language.CSharp, Language.Python };\n\n        /// <summary>\n        /// Data Points count of all timeslices of algorithm\n        /// </summary>\n        public long DataPoints => 2882;\n","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.CSharp/BasicTemplateIndiaIndexAlgorithm.cs#L77-L113","documentation":"Thrown in OnEndOfAlgorithm when Portfolio[Nifty].TotalSaleVolume > 0, meaning the NIFTY50 index received order fills. India market index symbols (NIFTY50) are non-tradable by design — the algorithm trades the JUNIORBEES ETF instead. Any fill on the index itself signals an engine-level tradability defect.","triggerScenarios":"Code calls MarketOrder(Nifty, qty) instead of MarketOrder(NiftyETF, qty), the engine sets IsTradable=true for Market.India index securities, or a Liquidate() call targets the Nifty symbol.","commonSituations":"Using the index symbol instead of the ETF symbol in order calls, India market-hours or security-type handling changes in the engine, or brokerage model updates affecting Market.India tradability.","solutions":["Confirm all MarketOrder/Liquidate calls use NiftyETF, never Nifty.","Log Securities[Nifty].IsTradable after Initialize to confirm it is false.","Check the IndiaOrderProperties and brokerage model for Market.India to ensure index fills are blocked.","Review OnData for any code path that passes Nifty to an order method."],"exampleFix":"// before\nMarketOrder(Nifty, 1);\n\n// after\nMarketOrder(NiftyETF, 1);","handlingStrategy":"validation","validationCode":"// Verify NIFTY50 index is non-tradable\nif (Securities[Nifty].IsTradable)\n{\n    Log($\"WARNING: {Nifty} is marked tradable\");\n}\n// Confirm ETF is the only traded security\nif (Portfolio[NiftyETF].TotalSaleVolume == 0)\n{\n    Log($\"No trades on ETF {NiftyETF} — check OnData logic\");\n}","typeGuard":"bool IsIndexNonTradable(Symbol sym) =>\n    Securities[sym].Type == SecurityType.Index && !Securities[sym].IsTradable;","tryCatchPattern":null,"preventionTips":["Use NiftyETF for all order calls, never Nifty.","Verify Market.India security initialization sets index IsTradable=false.","Log Securities[Nifty].IsTradable after Initialize.","Ensure IndiaOrderProperties apply only to ETF orders."],"tags":["quantconnect","index","india-market","tradability","regression-test","portfolio"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}