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]