public CrossOverIndicator(int movingAvgSmall, int movingAvgLarge)
 {
     if (movingAvgSmall >= movingAvgLarge)
     {
         throw new ArgumentException("Small must be smaller than large");
     }
     averageSmall = new MovingAverageCalculator(movingAvgSmall);
     averageLarge = new MovingAverageCalculator(movingAvgLarge);
 }
        private static void TestMovingAverageCalculator()
        {
            // no change
            const int len1 = 10;
            var       ma1  = new MovingAverageCalculator(len1);

            for (int i = 0; i < len1 * 2; i++)
            {
                ma1.NextValue(5.0);
                Assert((i < len1 - 1) != ma1.IsMature);
                Assert(ma1.MovingAverage == 5.0);
            }
            Assert(ma1.IsMature);
            Assert(ma1.MovingAverage == 5.0);
            Assert(ma1.Slope == 0);
            Assert(ma1.ExponentialMovingAverage == 5.0);
            Assert(ma1.ExponentialSlope == 0);

            // constant rise
            const int len2 = 10;
            var       ma2  = new MovingAverageCalculator(len2);

            for (int i = 0; i < len2; i++)
            {
                ma2.NextValue(i);
                Assert(ma2.MovingAverage == i / 2.0);
                Assert((i < len2 - 1) != ma2.IsMature);
            }
            Assert(ma2.IsMature);
            Assert(ma2.MovingAverage == 4.5);
            Assert(ma2.Slope == 0.5);
            Assert(ma2.ExponentialMovingAverage == 5.2393684801212155);
            Assert(ma2.ExponentialSlope == 0.83569589330639626);

            for (int i = len2; i < len2 * 2; i++)
            {
                ma2.NextValue(i);
                Assert(ma2.MovingAverage == i - 4.5);
            }

            // step function
            const int len3 = 10;
            var       ma3  = new MovingAverageCalculator(len3);

            for (int i = 0; i < len3; i++)
            {
                ma3.NextValue(i < 5 ? 0 : 1.0);
            }
            Assert(ma3.MovingAverage == 0.5);
            Assert(ma3.Slope == 0.05555555555555558);
            Assert(ma3.ExponentialMovingAverage == 0.63335216794679949);
            Assert(ma3.ExponentialSlope == 0.081477296011822409);

            // inverse step function
            const int len4 = 10;
            var       ma4  = new MovingAverageCalculator(len4);

            for (int i = 0; i < len4; i++)
            {
                ma4.NextValue(i < 5 ? 1.0 : 0);
            }
            Assert(ma4.MovingAverage == 0.5);
            Assert(ma4.Slope == -0.05555555555555558);
            Assert(ma4.ExponentialMovingAverage == 0.36664783205320051);
            Assert(ma4.ExponentialSlope == -0.081477296011822353);

            Console.WriteLine("TestMovingAverageCalculator OK");
        }
        public void MovingAverageCalculator()
        {
            // no change
            const int len1 = 10;
            var       ma1  = new MovingAverageCalculator(len1);

            for (int i = 0; i < len1 * 2; i++)
            {
                ma1.NextValue(5.0);
                Assert.AreNotEqual((i < len1 - 1), ma1.IsMature);
                Assert.AreEqual(ma1.MovingAverage, 5.0);
            }
            Assert.IsTrue(ma1.IsMature);
            Assert.AreEqual(ma1.MovingAverage, 5.0);
            Assert.AreEqual(ma1.Slope, 0.0);
            Assert.AreEqual(ma1.ExponentialMovingAverage, 5.0);
            Assert.AreEqual(ma1.ExponentialSlope, 0.0);

            // constant rise
            const int len2 = 10;
            var       ma2  = new MovingAverageCalculator(len2);

            for (int i = 0; i < len2; i++)
            {
                ma2.NextValue(i);
                Assert.AreEqual(ma2.MovingAverage, i / 2.0);
                Assert.AreNotEqual((i < len2 - 1), ma2.IsMature);
            }
            Assert.IsTrue(ma2.IsMature);
            Assert.AreEqual(ma2.MovingAverage, 4.5);
            Assert.AreEqual(ma2.Slope, 0.5);
            Assert.AreEqual(ma2.ExponentialMovingAverage, 5.2393684801212155);
            Assert.AreEqual(ma2.ExponentialSlope, 0.83569589330639626);

            for (int i = len2; i < len2 * 2; i++)
            {
                ma2.NextValue(i);
                Assert.AreEqual(ma2.MovingAverage, i - 4.5);
            }

            // step function
            const int len3 = 10;
            var       ma3  = new MovingAverageCalculator(len3);

            for (int i = 0; i < len3; i++)
            {
                ma3.NextValue(i < 5 ? 0 : 1.0);
            }
            Assert.AreEqual(ma3.MovingAverage, 0.5);
            Assert.AreEqual(ma3.Slope, 0.05555555555555558);
            Assert.AreEqual(ma3.ExponentialMovingAverage, 0.63335216794679949);
            Assert.AreEqual(ma3.ExponentialSlope, 0.081477296011822409);

            // inverse step function
            const int len4 = 10;
            var       ma4  = new MovingAverageCalculator(len4);

            for (int i = 0; i < len4; i++)
            {
                ma4.NextValue(i < 5 ? 1.0 : 0);
            }
            Assert.AreEqual(ma4.MovingAverage, 0.5);
            Assert.AreEqual(ma4.Slope, -0.05555555555555558);
            Assert.AreEqual(ma4.ExponentialMovingAverage, 0.36664783205320051);
            Assert.AreEqual(ma4.ExponentialSlope, -0.081477296011822353);
        }