{"record":{"id":"5325fed372b8e71f","repo":"QuantConnect/Lean","slug":"customoptionpricemodel-evaluate-was-never-called","errorCode":null,"errorMessage":"CustomOptionPriceModel.Evaluate() was never called","messagePattern":"CustomOptionPriceModel\\.Evaluate\\(\\) was never called","errorType":"exception","errorClass":"RegressionTestException","httpStatus":null,"severity":"error","filePath":"Algorithm.CSharp/CustomOptionPriceModelRegressionAlgorithm.cs","lineNumber":74,"sourceCode":"                var underlyingPrice = chain.Underlying.Price;\n                var atmContract = chain\n                    .OrderByDescending(x => x.Expiry)\n                    .ThenBy(x => Math.Abs(chain.Underlying.Price - x.Strike))\n                    .ThenByDescending(x => x.Right)\n                    .FirstOrDefault();\n\n                if (atmContract != null && atmContract.TheoreticalPrice > 0)\n                {\n                    MarketOrder(atmContract.Symbol, 1);\n                }\n            }\n        }\n\n        public override void OnEndOfAlgorithm()\n        {\n            if (_optionPriceModel.EvaluationCount == 0)\n            {\n                throw new RegressionTestException(\"CustomOptionPriceModel.Evaluate() was never called\");\n            }\n        }\n\n        private class CustomOptionPriceModel : IOptionPriceModel\n        {\n            public int EvaluationCount { get; private set; }\n            public OptionPriceModelResult Evaluate(OptionPriceModelParameters parameters)\n            {\n                EvaluationCount++;\n                var contract = parameters.Contract;\n                var underlying = contract.UnderlyingLastPrice;\n                var strike = contract.Strike;\n                var greeks = new Greeks(0.5m, 0.2m, 0.15m, 0.05m, 0.1m, 2.0m);\n\n                decimal intrinsicValue;\n                if (contract.Right == OptionRight.Call)\n                {\n                    intrinsicValue = Math.Max(0, underlying - strike);","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.CSharp/CustomOptionPriceModelRegressionAlgorithm.cs#L56-L92","documentation":"Asserts the custom option price model's Evaluate was invoked at least once. EvaluationCount is incremented inside CustomOptionPriceModel.Evaluate; if it is 0 at OnEndOfAlgorithm, the option never priced a contract (no evaluation request reached the model).","triggerScenarios":"Assigning an IOptionPriceModel to an option contract (e.g., SetOptionPriceModel or option.PriceModel = ...) but the engine never requests a price evaluation because no Greek/price query occurred, or the model was assigned to the wrong object.","commonSituations":"Model set after the option was added but the algorithm never accessed Greeks/TheoreticalPrice, so evaluation was never triggered; the ATM-contract branch (atmContract != null && TheoreticalPrice > 0) never executed because no contract resolved; or the model was assigned to a non-option security.","solutions":["Ensure the algorithm accesses an option contract's price/Greeks (e.g., evaluates atmContract.TheoreticalPrice) so the engine invokes Evaluate.","Confirm SetOptionPriceModel is called on the option security (not the underlying) and that the option chain resolves at least one contract.","Verify the ATM selection logic actually picks a contract; a null atmContract skips the evaluation path.","Run over a date range with active option data so the chain populates and pricing is requested."],"exampleFix":"// before: model set but never queried, Evaluate never runs\noption.SetOptionPriceModel(new CustomOptionPriceModel());\n// ...no Greek/price access...\n\n// after: force an evaluation by reading the theoretical price\nvar atm = OptionChainProvider.GetOptionContractList(option.Symbol, Time).First();\nvar _ = atm.TheoreticalPrice; // triggers Evaluate, increments EvaluationCount","handlingStrategy":"validation","validationCode":"// Confirm an option contract resolves and force an evaluation\nvar chain = OptionChainProvider.GetOptionContractList(option.Symbol, Time);\nif (!chain.Any()) Log(\"No option contracts; price model will not be evaluated.\");","typeGuard":"bool HasContracts(IEnumerable<Symbol> chain) => chain.Any();","tryCatchPattern":null,"preventionTips":["Set the price model on the option security (not the underlying).","Access a contract's TheoreticalPrice/Greeks so Evaluate is invoked.","Run over a date range with active option data so the chain populates."],"tags":["regression-test","option-price-model","options","model-invocation"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}