From 8d51ac1c803340e4834b91ebb7a3a913e7ecbc0a Mon Sep 17 00:00:00 2001 From: mkzung <103102868+mkzung@users.noreply.github.com> Date: Sun, 16 Aug 2026 23:24:15 +0500 Subject: [PATCH] Stop McClellanOscillator counting one shared bar twice --- Indicators/McClellanOscillator.cs | 4 +++- Tests/Indicators/McClellanOscillatorTests.cs | 3 ++- Tests/Indicators/McClellanSummationIndexTests.cs | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Indicators/McClellanOscillator.cs b/Indicators/McClellanOscillator.cs index 51b139b99f81..bc3fe4814929 100644 --- a/Indicators/McClellanOscillator.cs +++ b/Indicators/McClellanOscillator.cs @@ -50,7 +50,9 @@ public class McClellanOscillator : TradeBarIndicator, IIndicatorWarmUpPeriodProv /// /// Required period, in data points, for the indicator to be ready and fully initialized. /// - public int WarmUpPeriod => EMASlow.WarmUpPeriod + ADDifference.WarmUpPeriod; + /// The two periods share a bar: EMASlow is fed by ADDifference and only + /// once it is ready, so ADDifference's last warm-up bar is EMASlow's first input. + public int WarmUpPeriod => EMASlow.WarmUpPeriod + ADDifference.WarmUpPeriod - 1; /// /// Initializes a new instance of the class diff --git a/Tests/Indicators/McClellanOscillatorTests.cs b/Tests/Indicators/McClellanOscillatorTests.cs index 90d7811a3f62..de26030b37b9 100644 --- a/Tests/Indicators/McClellanOscillatorTests.cs +++ b/Tests/Indicators/McClellanOscillatorTests.cs @@ -58,11 +58,12 @@ public override void WarmsUpProperly() indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, Close = i, Volume = 1, Time = reference.AddMinutes(i) }); indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, Close = i, Volume = 1, Time = reference.AddMinutes(i) }); indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, Close = i, Volume = 1, Time = reference.AddMinutes(i) }); + + Assert.AreEqual(i == indicator.WarmUpPeriod, indicator.IsReady); } Assert.AreEqual(0m, indicator.Current.Value); Assert.AreEqual(indicator.WarmUpPeriod * 3, indicator.Samples); - Assert.IsTrue(indicator.IsReady); } [Test] diff --git a/Tests/Indicators/McClellanSummationIndexTests.cs b/Tests/Indicators/McClellanSummationIndexTests.cs index 919babcdd987..95848d36f100 100644 --- a/Tests/Indicators/McClellanSummationIndexTests.cs +++ b/Tests/Indicators/McClellanSummationIndexTests.cs @@ -57,11 +57,12 @@ public override void WarmsUpProperly() indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, Close = i, Volume = 1, Time = reference.AddMinutes(i) }); indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, Close = i, Volume = 1, Time = reference.AddMinutes(i) }); indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, Close = i, Volume = 1, Time = reference.AddMinutes(i) }); + + Assert.AreEqual(i == indicator.WarmUpPeriod, indicator.IsReady); } Assert.AreEqual(60m, indicator.Current.Value); Assert.AreEqual(indicator.WarmUpPeriod * 3, indicator.Samples); - Assert.IsTrue(indicator.IsReady); } [Test]