From bae9d60a3983b6b9e3ea93448e81a14b24fbd1d4 Mon Sep 17 00:00:00 2001 From: Martin Molinero Date: Thu, 1 Oct 2026 10:49:46 -0300 Subject: [PATCH] Support SetBenchmark(null) to disable the benchmark Co-Authored-By: Claude Opus 5.5 (1M context) --- Algorithm/QCAlgorithm.cs | 9 +++++- Tests/Algorithm/AlgorithmBenchmarkTests.cs | 32 ++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/Algorithm/QCAlgorithm.cs b/Algorithm/QCAlgorithm.cs index d6987b6c1fcc..64ae348e03d4 100644 --- a/Algorithm/QCAlgorithm.cs +++ b/Algorithm/QCAlgorithm.cs @@ -1527,7 +1527,7 @@ public void SetBenchmark(string ticker) /// /// Sets the benchmark used for computing statistics of the algorithm to the specified symbol /// - /// symbol to use as the benchmark + /// symbol to use as the benchmark, null to disable the benchmark [DocumentationAttribute(TradingAndOrders)] [DocumentationAttribute(SecuritiesAndPortfolio)] [DocumentationAttribute(Indicators)] @@ -1538,6 +1538,13 @@ public void SetBenchmark(Symbol symbol) throw new InvalidOperationException(Messages.QCAlgorithm.SetBenchmarkAlreadyInitialized()); } + if (symbol == null) + { + // Equivalent to no benchmark + Benchmark = new FuncBenchmark(_ => 0); + return; + } + // Create our security benchmark Benchmark = SecurityBenchmark.CreateInstance(Securities, symbol); } diff --git a/Tests/Algorithm/AlgorithmBenchmarkTests.cs b/Tests/Algorithm/AlgorithmBenchmarkTests.cs index 5d012667b09c..138ea23f8bbf 100644 --- a/Tests/Algorithm/AlgorithmBenchmarkTests.cs +++ b/Tests/Algorithm/AlgorithmBenchmarkTests.cs @@ -149,6 +149,38 @@ public void PythonSetBenchmarkThrowsDescriptiveErrorForUnsupportedBenchmarkType( } } + [TestCase(Language.CSharp)] + [TestCase(Language.Python)] + public void NullBenchmarkDisablesTheBenchmark(Language language) + { + var algorithm = new QCAlgorithm(); + var dataManager = new DataManagerStub(algorithm, new MockDataFeed()); + algorithm.SubscriptionManager.SetDataManager(dataManager); + + if (language == Language.CSharp) + { + algorithm.SetBenchmark((Symbol)null); + } + else + { + using var _ = Py.GIL(); + using var module = PyModule.FromString(nameof(NullBenchmarkDisablesTheBenchmark), @" +def set_benchmark(algorithm): + algorithm.set_benchmark(None) +"); + using var pyAlgorithm = algorithm.ToPython(); + using var setBenchmark = module.GetAttr("set_benchmark"); + setBenchmark.Invoke(pyAlgorithm); + } + + algorithm.PostInitialize(); + + // The default brokerage model benchmark is not used and no benchmark security is added + Assert.IsInstanceOf(algorithm.Benchmark); + Assert.AreEqual(0m, algorithm.Benchmark.Evaluate(new DateTime(2024, 1, 2))); + Assert.IsEmpty(algorithm.Securities); + } + [Test] public void BenchmarkIsNotInitializeWithCustomSecurityInitializer() {