{"record":{"id":"269a65bf28502601","repo":"QuantConnect/Lean","slug":"custommargininterestratemodel-was-not-called","errorCode":null,"errorMessage":"CustomMarginInterestRateModel was not called","messagePattern":"CustomMarginInterestRateModel was not called","errorType":"exception","errorClass":"RegressionTestException","httpStatus":null,"severity":"error","filePath":"Algorithm.CSharp/CustomMarginInterestRateModelAlgorithm.cs","lineNumber":75,"sourceCode":"            if (orderEvent.Status == OrderStatus.Filled)\n            {\n                _cashAfterOrder = Portfolio.Cash;\n            }\n        }\n\n        public override void OnEndOfAlgorithm()\n        {\n            var security = Securities[_spy];\n            var marginInterestRateModel = security.MarginInterestRateModel as CustomMarginInterestRateModel;\n\n            if (marginInterestRateModel == null)\n            {\n                throw new RegressionTestException(\"CustomMarginInterestRateModel was not set\");\n            }\n\n            if (marginInterestRateModel.CallCount == 0)\n            {\n                throw new RegressionTestException(\"CustomMarginInterestRateModel was not called\");\n            }\n\n            var expectedCash = _cashAfterOrder * (decimal)Math.Pow(1 + (double)marginInterestRateModel.InterestRate, marginInterestRateModel.CallCount);\n\n            // add a tolerance since using Math.Pow(double, double) given the lack of a decimal overload\n            if (Math.Abs(Portfolio.Cash - expectedCash) > 1e-10m)\n            {\n                throw new RegressionTestException($\"Expected cash {expectedCash} but got {Portfolio.Cash}\");\n            }\n        }\n\n        public class CustomMarginInterestRateModel : IMarginInterestRateModel\n        {\n            public decimal InterestRate { get; } = 0.01m;\n\n            public int CallCount { get; private set; }\n\n            public void ApplyMarginInterestRate(MarginInterestRateParameters marginInterestRateParameters)","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.CSharp/CustomMarginInterestRateModelAlgorithm.cs#L57-L93","documentation":"Asserts the custom model was actually invoked. CallCount is incremented inside ApplyMarginInterestRate only when the position value is positive; if CallCount is still 0, ApplyMarginInterestRate never ran with a long position. Lean calls ApplyMarginInterestRate each day at margin-application time, so zero calls means either the model was not wired in or there was never a positive held position.","triggerScenarios":"Holding a position but the framework never calls ApplyMarginInterestRate (model not registered in the scheduler), or holding a position but GetQuantityValue returns zero/negative so the model's internal guard skips the increment.","commonSituations":"Margin interest only applies to leveraged/long positions; if the security never held positive quantity or the holdings quantity was zero at evaluation time, the guard `positionValue.Amount > 0` is false. Also seen when the brokerage/time manager skips daily margin application for the resolution used.","solutions":["Confirm the algorithm opens and holds a long position for at least one margin-application interval (the test uses SetHoldings(_spy, 1)).","Verify GetQuantityValue returns a positive amount for the held quantity so the guard increments CallCount.","Ensure the security's MarginInterestRateModel is the custom instance (see error 48) so its ApplyMarginInterestRate is the one scheduled.","Run with hour/daily resolution over a multi-day range so the daily margin-application tick fires."],"exampleFix":"// before: guard never true because position is flat at evaluation\nif (positionValue.Amount > 0) { CallCount++; }\n\n// after: hold the position so evaluation sees a positive amount\npublic override void OnData(Slice slice)\n{\n    if (!Portfolio.Invested) SetHoldings(_spy, 1); // keep long through margin ticks\n}","handlingStrategy":"validation","validationCode":"// Verify a positive position exists before expecting margin application\nif (!Portfolio.Invested || Portfolio[_spy].Quantity <= 0)\n    Log(\"No positive position; custom margin model will not be invoked.\");","typeGuard":"bool HasPositivePosition(Security s) => s.Holdings.Quantity > 0;","tryCatchPattern":null,"preventionTips":["Hold a long position through at least one margin-application tick so ApplyMarginInterestRate runs.","Confirm GetQuantityValue returns a positive amount for the held quantity.","Use a resolution/date range that includes the daily margin-application event."],"tags":["regression-test","margin-interest-rate","model-invocation","holdings"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}