diff --git a/Indicators/IchimokuKinkoHyo.cs b/Indicators/IchimokuKinkoHyo.cs index 6f7cbdadaba2..5c366ce678d8 100644 --- a/Indicators/IchimokuKinkoHyo.cs +++ b/Indicators/IchimokuKinkoHyo.cs @@ -147,51 +147,18 @@ public IchimokuKinkoHyo(string name, int tenkanPeriod = 9, int kijunPeriod = 26, KijunMinimum = new Minimum(name + "_KijunMin", kijunPeriod); SenkouBMaximum = new Maximum(name + "_SenkouBMaximum", senkouBPeriod); SenkouBMinimum = new Minimum(name + "_SenkouBMinimum", senkouBPeriod); - DelayedTenkanSenkouA = new Delay(name + "DelayedTenkan", senkouADelayPeriod); - DelayedKijunSenkouA = new Delay(name + "DelayedKijun", senkouADelayPeriod); - DelayedMaximumSenkouB = new Delay(name + "DelayedMax", senkouBDelayPeriod); - DelayedMinimumSenkouB = new Delay(name + "DelayedMin", senkouBDelayPeriod); - Chikou = new Delay(name + "_Chikou", senkouADelayPeriod); - - SenkouA = new FunctionalIndicator( - name + "_SenkouA", - input => SenkouA.IsReady ? (DelayedTenkanSenkouA.Current.Value + DelayedKijunSenkouA.Current.Value) / 2 : decimal.Zero, - senkouA => DelayedTenkanSenkouA.IsReady && DelayedKijunSenkouA.IsReady, - () => - { - Tenkan.Reset(); - Kijun.Reset(); - }); + DelayedMaximumSenkouB = new Delay(name + "DelayedMax", senkouBDelayPeriod).Of(SenkouBMaximum); + DelayedMinimumSenkouB = new Delay(name + "DelayedMin", senkouBDelayPeriod).Of(SenkouBMinimum); - SenkouB = new FunctionalIndicator( - name + "_SenkouB", - input => SenkouB.IsReady ? (DelayedMaximumSenkouB.Current.Value + DelayedMinimumSenkouB.Current.Value) / 2 : decimal.Zero, - senkouA => DelayedMaximumSenkouB.IsReady && DelayedMinimumSenkouB.IsReady, - () => - { - Tenkan.Reset(); - Kijun.Reset(); - }); + Tenkan = TenkanMaximum.Plus(TenkanMinimum).Over(2m); + DelayedTenkanSenkouA = new Delay(name + "DelayedTenkan", senkouADelayPeriod).Of(Tenkan); - Tenkan = new FunctionalIndicator( - name + "_Tenkan", - input => Tenkan.IsReady ? (TenkanMaximum.Current.Value + TenkanMinimum.Current.Value) / 2 : decimal.Zero, - tenkan => TenkanMaximum.IsReady && TenkanMinimum.IsReady, - () => - { - TenkanMaximum.Reset(); - TenkanMinimum.Reset(); - }); + Kijun = KijunMaximum.Plus(KijunMinimum).Over(2m); + DelayedKijunSenkouA = new Delay(name + "DelayedKijun", senkouADelayPeriod).Of(Kijun); - Kijun = new FunctionalIndicator( - name + "_Kijun", - input => Kijun.IsReady ? (KijunMaximum.Current.Value + KijunMinimum.Current.Value) / 2 : decimal.Zero, - kijun => KijunMaximum.IsReady && KijunMinimum.IsReady, - () => - { - KijunMaximum.Reset(); - KijunMinimum.Reset(); - }); + SenkouA = DelayedTenkanSenkouA.Plus(DelayedKijunSenkouA).Over(2m); + SenkouB = DelayedMaximumSenkouB.Plus(DelayedMinimumSenkouB).Over(2m); + Chikou = new Delay(name + "_Chikou", senkouADelayPeriod); } /// @@ -212,22 +179,10 @@ protected override decimal ComputeNextValue(IBaseDataBar input) { TenkanMaximum.Update(input.EndTime, input.High); TenkanMinimum.Update(input.EndTime, input.Low); - Tenkan.Update(input.EndTime, input.Close); - if (Tenkan.IsReady) DelayedTenkanSenkouA.Update(input.EndTime, Tenkan.Current.Value); - KijunMaximum.Update(input.EndTime, input.High); KijunMinimum.Update(input.EndTime, input.Low); - Kijun.Update(input.EndTime, input.Close); - if (Kijun.IsReady) DelayedKijunSenkouA.Update(input.EndTime, Kijun.Current.Value); - - SenkouA.Update(input.EndTime, input.Close); - - SenkouB.Update(input.EndTime, input.Close); SenkouBMaximum.Update(input.EndTime, input.High); - if (SenkouBMaximum.IsReady) DelayedMaximumSenkouB.Update(input.EndTime, SenkouBMaximum.Current.Value); SenkouBMinimum.Update(input.EndTime, input.Low); - if (SenkouBMinimum.IsReady) DelayedMinimumSenkouB.Update(input.EndTime, SenkouBMinimum.Current.Value); - Chikou.Update(input.EndTime, input.Close); return input.Close; diff --git a/Tests/Indicators/IchimokuKinkoHyoTests.cs b/Tests/Indicators/IchimokuKinkoHyoTests.cs index 68feaf0078eb..ef19b5ce846e 100644 --- a/Tests/Indicators/IchimokuKinkoHyoTests.cs +++ b/Tests/Indicators/IchimokuKinkoHyoTests.cs @@ -1,4 +1,4 @@ -/* +/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * @@ -36,7 +36,7 @@ protected override IndicatorBase CreateIndicator() protected override Action, double> Assertion => (indicator, expected) => - Assert.AreEqual(expected, (double) ((IchimokuKinkoHyo) indicator).Tenkan.Current.Value, 1e-3); + Assert.AreEqual(expected, (double)((IchimokuKinkoHyo)indicator).Tenkan.Current.Value, 1e-3); [Test] public void ComparesWithExternalDataTenkanMaximum() @@ -166,5 +166,25 @@ public void ComparesWithExternalDataDelayedMinimumSenkouB() (ind, expected) => Assert.AreEqual(expected, (double)((IchimokuKinkoHyo)ind).DelayedMinimumSenkouB.Current.Value) ); } + + [Test] + public void ComponentsAreNonZeroWhenIndicatorIsReady() + { + var indicator = new IchimokuKinkoHyo(2, 3, 2, 4, 2, 2); + var date = new DateTime(2017, 1, 1); + + for (int i = 1; i <= indicator.WarmUpPeriod; i++) + { + var tradeBar = new TradeBar(date + TimeSpan.FromDays(i), Symbols.SPY, + 100 * i, 200 * i, 100 * i, 200 * i, 500 * i); + indicator.Update(tradeBar); + } + + Assert.IsTrue(indicator.IsReady); + Assert.AreNotEqual(0m, indicator.Tenkan.Current.Value); + Assert.AreNotEqual(0m, indicator.Kijun.Current.Value); + Assert.AreNotEqual(0m, indicator.SenkouA.Current.Value); + Assert.AreNotEqual(0m, indicator.SenkouB.Current.Value); + } } -} \ No newline at end of file +}