コード例 #1
0
        public void CouldUseWindowCursor()
        {
            SortedMap <int, double> sm = new SortedMap <int, double>();

            var count = 100;

            for (int i = 0; i < count; i++)
            {
                sm.Add(i, i);
            }

            var window = sm.Window(10);

            // NB no type annotations needed to get the same result
            // Even though `.Source` saves a great deal of typing, manual construction is still a dealbreaker
            // Extension methods are smart and keep all types info without requiring any type annotations
            var windowLong = new Window <int, double, SortedMapCursor <int, double> >(sm.GetEnumerator(), 10).Source;

            foreach (var pair in window)
            {
                var expected = ((2 * pair.Key - 10 + 1) / 2.0) * 10;
                Assert.AreEqual(expected, pair.Value.Values.Sum());
                Console.WriteLine(pair.Value.Values.Sum());
                //Console.WriteLine(keyValuePair.Value.Aggregate("", (st,kvp) => st + "," + kvp.Value));
            }
        }
コード例 #2
0
ファイル: MiscCursorsTests.cs プロジェクト: lulzzz/Spreads
        public void CouldCalculateAverageOnMovingWindowWithStep()
        {
            var sm = new SortedMap <DateTime, double>();

            var count = 100000;

            for (int i = 0; i < count; i++)
            {
                sm.Add(DateTime.UtcNow.Date.AddSeconds(i), i);
            }

            // slow implementation
            var sw = new Stopwatch();

            sw.Start();
            var ma = sm.Window(20, 2);//.ToSortedMap();
            var c  = 1;

            foreach (var m in ma)
            {
                var innersm = m.Value;//.ToSortedMap();
                if (innersm.Values.Average() != c + 8.5)
                {
                    Console.WriteLine(m.Value.Values.Average());
                    throw new ApplicationException("Invalid value");
                }
                c++;
                c++;
            }
            sw.Stop();
            Console.WriteLine($"Final c: {c}");
            Console.WriteLine("Window MA, elapsed: {0}, ops: {1}", sw.ElapsedMilliseconds, (int)((double)count / (sw.ElapsedMilliseconds / 1000.0)));
            Console.WriteLine("Calculation ops: {0}", (int)((double)count * 20.0 / (sw.ElapsedMilliseconds / 1000.0)));
        }
コード例 #3
0
        public void CouldUseWindowCursorWithIncomplete()
        {
            SortedMap <int, double> sm = new SortedMap <int, double>();

            var count = 20;

            for (int i = 0; i < count; i++)
            {
                sm.Add(i, i);
            }

            var window = sm.Window(10, true);

            foreach (var pair in window)
            {
                Assert.AreEqual(Math.Min(pair.Key + 1, 10), pair.Value.Count());
            }

            var window2 = sm.Window(count * 2, true);

            foreach (var pair in window2)
            {
                Assert.AreEqual(sm.Values.Take(pair.Key + 1).Sum(), pair.Value.Values.Sum());
                Assert.AreEqual(pair.Key + 1, pair.Value.Count());
            }

            var window3 = sm.Window(3, Lookup.EQ);

            foreach (var pair in window3)
            {
                Console.WriteLine($"{pair.Key}:");
                foreach (var keyValuePair in pair.Value)
                {
                    Console.WriteLine($"{keyValuePair.Key} - {keyValuePair.Value}");
                }

                Console.WriteLine("--------------");
            }
        }
コード例 #4
0
ファイル: MiscCursorsTests.cs プロジェクト: b-e-n-j/Spreads
        public void CouldCalculateAverageOnMovingWindowWithStep() {
            var sm = new SortedMap<DateTime, double>();

            var count = 100000;

            for (int i = 0; i < count; i++) {
                sm.Add(DateTime.UtcNow.Date.AddSeconds(i), i);
            }

            // slow implementation
            var sw = new Stopwatch();
            sw.Start();
            var ma = sm.Window(20, 2);//.ToSortedMap();
            var c = 1;
            foreach (var m in ma) {
                var innersm = m.Value;//.ToSortedMap();
                if (innersm.Values.Average() != c + 8.5) {
                    Console.WriteLine(m.Value.Values.Average());
                    throw new ApplicationException("Invalid value");
                }
                c++;
                c++;
            }
            sw.Stop();
            Console.WriteLine($"Final c: {c}");
            Console.WriteLine("Window MA, elapsed: {0}, ops: {1}", sw.ElapsedMilliseconds, (int)((double)count / (sw.ElapsedMilliseconds / 1000.0)));
            Console.WriteLine("Calculation ops: {0}", (int)((double)count * 20.0 / (sw.ElapsedMilliseconds / 1000.0)));
        }
コード例 #5
0
ファイル: SpanOpTests.cs プロジェクト: lulzzz/Spreads
        public void TypeSystemSurvivesViolentAbuse()
        {
            var count = 1000;

            #region Create data

            var sm = new SortedMap <int, double>();
            sm.Add(0, 0); // make irregular, it's faster but more memory
            for (int i = 2; i <= count; i++)
            {
                sm.Add(i, i);
            }

            #endregion Create data

            for (int round = 0; round < 20; round++)
            {
                var window = sm.Window(20).Window(20).Window(20).Window(20).Window(20); // this becomes too much: .Window(20).Window(20).Window(20);

                var c = 0;
                using (Benchmark.Run("Struct", count * 1000_000))
                {
                    foreach (var keyValuePair in window)
                    {
                        if (keyValuePair.Key >= 0)
                        {
                            c++;
                        }
                    }
                }

                using (Benchmark.Run("Struct Lazy", count * 1000_000))
                {
                    var cursor = window.GetEnumerator();
                    while (cursor.MoveNext())
                    {
                        if (cursor.CurrentKey >= 0)
                        {
                            c++;
                        }
                    }
                }

                if (c < 0)
                {
                    Console.WriteLine($"Count: {c}");
                }

                var window2 = sm.Window_(20).Window_(20).Window_(20).Window_(20).Window_(20);
                var c2      = 0;
                using (Benchmark.Run("Interface", count * 1000_000))
                {
                    foreach (var keyValuePair in window2)
                    {
                        if (keyValuePair.Key >= 0)
                        {
                            c2++;
                        }
                    }
                }
                if (c2 < 0)
                {
                    Console.WriteLine($"Count2: {c2}");
                }
            }

            Benchmark.Dump("MOPS is scaled by x1M, so it is OPS");
        }
コード例 #6
0
ファイル: SpanOpTests.cs プロジェクト: lulzzz/Spreads
        public void WindowDirectAndIndirectSpanOpBenchmark()
        {
            Settings.DoAdditionalCorrectnessChecks = false;

            var count = 100000;
            var width = 20;
            var sm    = new SortedMap <int, double>();

            sm.Add(0, 0); // make irregular, it's faster but more memory
            for (int i = 2; i <= count; i++)
            {
                sm.Add(i, i);
            }

            var op     = new WindowOnlineOp <int, double, SortedMapCursor <int, double> >();
            var spanOp =
                new SpanOpCount <int, double, Range <int, double, SortedMapCursor <int, double> >,
                                 SortedMapCursor <int, double>, WindowOnlineOp <int, double, SortedMapCursor <int, double> > >(20, false,
                                                                                                                               op);
            var window =
                new SpanOpImpl <int,
                                double,
                                Range <int, double, SortedMapCursor <int, double> >,
                                SpanOpCount <int, double, Range <int, double, SortedMapCursor <int, double> >, SortedMapCursor <int, double>, WindowOnlineOp <int, double, SortedMapCursor <int, double> > >,
                                SortedMapCursor <int, double>
                                >(sm.GetEnumerator(), spanOp).Source
                .Map(x =>
            {
                var sum = 0.0;
                var c   = 0;
                foreach (var keyValuePair in x.Source)
                {
                    sum += keyValuePair.Value;
                    c++;
                }
                return(sum / c);        // x.CursorDefinition.Count TODO
            });

            var spanOpCombined =
                new SpanOp <int, double, Range <int, double, SortedMapCursor <int, double> >,
                            SortedMapCursor <int, double>, WindowOnlineOp <int, double, SortedMapCursor <int, double> > >(20, false,
                                                                                                                          op, sm.comparer);
            var windowCombined =
                new SpanOpImpl <int,
                                double,
                                Range <int, double, SortedMapCursor <int, double> >,
                                SpanOp <int, double, Range <int, double, SortedMapCursor <int, double> >, SortedMapCursor <int, double>, WindowOnlineOp <int, double, SortedMapCursor <int, double> > >,
                                SortedMapCursor <int, double>
                                >(sm.GetEnumerator(), spanOpCombined).Source
                .Map(x =>
            {
                var sum = 0.0;
                var c   = 0;
                foreach (var keyValuePair in x.Source)
                {
                    sum += keyValuePair.Value;
                    c++;
                }
                return(sum / c);    // x.CursorDefinition.Count TODO
            });

            var windowExtension = sm.Window(width).Map(x =>
            {
                var sum = 0.0;
                var c   = 0;
                foreach (var keyValuePair in x)
                {
                    sum += keyValuePair.Value;
                    c++;
                }
                return(sum / c); // x.CursorDefinition.Count TODO
            });

            for (int round = 0; round < 20; round++)
            {
                double sum1 = 0.0;
                using (Benchmark.Run("Window SpanOpCount", count * width))
                {
                    foreach (var keyValuePair in window)
                    {
                        sum1 += keyValuePair.Value;
                    }
                }

                double sum2 = 0.0;
                using (Benchmark.Run("Window SpanOp", count * width))
                {
                    foreach (var keyValuePair in windowCombined)
                    {
                        sum2 += keyValuePair.Value;
                    }
                }

                double sum3 = 0.0;
                using (Benchmark.Run("Window Extension", count * width))
                {
                    foreach (var keyValuePair in windowExtension)
                    {
                        sum3 += keyValuePair.Value;
                    }
                }

                Assert.AreEqual(sum1, sum2);
                Assert.AreEqual(sum1, sum3);
            }

            Benchmark.Dump($"The window width is {width}.");
        }
コード例 #7
0
ファイル: SpanOpTests.cs プロジェクト: lulzzz/Spreads
        public void SMADirectAndIndirectSpanOpBenchmark()
        {
            Settings.DoAdditionalCorrectnessChecks = false;

            var count = 1000000;
            var width = 20;
            var sm    = new SortedMap <int, double>();

            sm.Add(0, 0); // make irregular, it's faster but more memory
            for (int i = 2; i <= count; i++)
            {
                sm.Add(i, i);
            }

            var directSMA =
                new SpanOpImpl <int,
                                double,
                                double,
                                MAvgCount <int, double, SortedMapCursor <int, double> >,
                                SortedMapCursor <int, double>
                                >(sm.GetEnumerator(), new MAvgCount <int, double, SortedMapCursor <int, double> >(width, false)).Source;

            var indirectSma =
                new SpanOpImpl <int,
                                double,
                                double,
                                SpanOpCount <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >,
                                SortedMapCursor <int, double>
                                >(sm.GetEnumerator(),
                                  new SpanOpCount <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >(width, false, new SumAvgOnlineOp <int, double, SortedMapCursor <int, double> >())).Source;

            var indirectSmaCombined =
                new SpanOpImpl <int,
                                double,
                                double,
                                SpanOp <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >,
                                SortedMapCursor <int, double>
                                >(sm.GetEnumerator(),
                                  new SpanOp <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >(width, false, new SumAvgOnlineOp <int, double, SortedMapCursor <int, double> >(), sm.comparer)).Source;

            var extensionSma = sm.SMA(width);

            var windowSma = sm.Window(width).Map(x =>
            {
                var sum = 0.0;
                var c   = 0;
                foreach (var keyValuePair in x)
                {
                    sum += keyValuePair.Value;
                    c++;
                }
                return(sum / c); // x.CursorDefinition.Count TODO
            });

            for (int round = 0; round < 20; round++)
            {
                double sum1 = 0.0;
                using (Benchmark.Run("SMA Direct", count * width))
                {
                    foreach (var keyValuePair in directSMA)
                    {
                        sum1 += keyValuePair.Value;
                    }
                }

                double sum2 = 0.0;
                using (Benchmark.Run("SMA Indirect", count * width))
                {
                    foreach (var keyValuePair in indirectSma)
                    {
                        sum2 += keyValuePair.Value;
                    }
                }

                double sum2_2 = 0.0;
                using (Benchmark.Run("SMA Indirect Combined", count * width))
                {
                    foreach (var keyValuePair in indirectSmaCombined)
                    {
                        sum2_2 += keyValuePair.Value;
                    }
                }

                double sum2_3 = 0.0;
                using (Benchmark.Run("SMA Extension", count * width))
                {
                    foreach (var keyValuePair in extensionSma)
                    {
                        sum2_3 += keyValuePair.Value;
                    }
                }

                double sum3 = 0.0;
                using (Benchmark.Run("SMA Window", count * width))
                {
                    foreach (var keyValuePair in windowSma)
                    {
                        sum3 += keyValuePair.Value;
                    }
                }

                var sumxx = 0.0;
                using (Benchmark.Run("SortedMap", count))
                {
                    foreach (var keyValuePair in sm)
                    {
                        sumxx += keyValuePair.Value;
                    }
                }

                Assert.AreEqual(sum1, sum2);
                Assert.AreEqual(sum1, sum2_2);
                Assert.AreEqual(sum1, sum2_3);
                Assert.AreEqual(sum1, sum3);
            }

            Benchmark.Dump($"The window width is {width}. SMA MOPS are calculated as a number of calculated values multiplied by width, " +
                           $"which is equivalent to the total number of cursor moves for Window case. SortedMap line is for reference - it is the " +
                           $"speed of raw iteration over SM without Windows overheads.");
        }
コード例 #8
0
ファイル: SpanOpTests.cs プロジェクト: lulzzz/Spreads
        public void CouldCalculateSMAWithWidth()
        {
            var count = 20;
            var sm    = new SortedMap <int, double>();

            for (int i = 1; i <= count; i++)
            {
                sm.Add(i, i);
            }

            DoTest(Lookup.EQ);
            DoTest(Lookup.GE);
            DoTest(Lookup.GT);
            DoTest(Lookup.LE);
            DoTest(Lookup.LT);

            DoTestViaSpanOpWidth(Lookup.EQ);
            DoTestViaSpanOpWidth(Lookup.GE);
            DoTestViaSpanOpWidth(Lookup.GT);
            DoTestViaSpanOpWidth(Lookup.LE);
            DoTestViaSpanOpWidth(Lookup.LT);

            void DoTest(Lookup lookup)
            {
                // width 9 is the same as count = 10 for the regular int series
                var smaOp     = new MAvgWidth <int, double, SortedMapCursor <int, double> >(9, lookup);
                var smaCursor =
                    new SpanOpImpl <int,
                                    double,
                                    double,
                                    MAvgWidth <int, double, SortedMapCursor <int, double> >,
                                    SortedMapCursor <int, double>
                                    >(sm.GetEnumerator(), smaOp);

                // this monster type must be hidden in the same way Lag hides its implementation
                Series <int, double, SpanOpImpl <int, double, double, MAvgWidth <int, double, SortedMapCursor <int, double> >, SortedMapCursor <int, double> > > smaSeries;

                smaSeries = smaCursor.Source;

                var sm2 = smaSeries.ToSortedMap();

                Assert.AreEqual(sm2.First, smaSeries.First);
                Assert.AreEqual(sm2.Last, smaSeries.Last);

                Assert.True(SeriesContract.MoveAtShouldWorkOnLazySeries(smaSeries));
                Assert.True(SeriesContract.ClonedCursorsAreIndependent(smaSeries));

                if (lookup == Lookup.EQ || lookup == Lookup.GE)
                {
                    var trueSma = sm.Window(10).Map(x => x.Values.Average());
                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                if (lookup == Lookup.GT)
                {
                    var trueSma = sm.Window(11).Map(x => x.Values.Average());
                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                if (lookup == Lookup.LE)
                {
                    var smaOp1  = new MAvgCount <int, double, SortedMapCursor <int, double> >(10, true);
                    var trueSma =
                        new SpanOpImpl <int,
                                        double,
                                        double,
                                        MAvgCount <int, double, SortedMapCursor <int, double> >,
                                        SortedMapCursor <int, double>
                                        >(sm.GetEnumerator(), smaOp1).Source;

                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                if (lookup == Lookup.LT)
                {
                    var smaOp1  = new MAvgCount <int, double, SortedMapCursor <int, double> >(9, true);
                    var trueSma =
                        new SpanOpImpl <int,
                                        double,
                                        double,
                                        MAvgCount <int, double, SortedMapCursor <int, double> >,
                                        SortedMapCursor <int, double>
                                        >(sm.GetEnumerator(), smaOp1).Source;

                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                Debug.WriteLine("SMA");
                foreach (var keyValuePair in smaSeries)
                {
                    Debug.WriteLine($"{keyValuePair.Key} - {keyValuePair.Value}");
                }
            }

            void DoTestViaSpanOpWidth(Lookup lookup)
            {
                // width 9 is the same as count = 10 for the regular int series

                var onlineOp  = new SumAvgOnlineOp <int, double, SortedMapCursor <int, double> >();
                var smaOp     = new SpanOpWidth <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >(9, lookup, onlineOp);
                var smaCursor =
                    new SpanOpImpl <int,
                                    double,
                                    double,
                                    SpanOpWidth <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >,
                                    SortedMapCursor <int, double>
                                    >(sm.GetEnumerator(), smaOp);

                // this monster type must be hidden in the same way Lag hides its implementation

                Series <int, double, SpanOpImpl <int, double, double, SpanOpWidth <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >, SortedMapCursor <int, double> > > smaSeries;

                smaSeries = smaCursor.Source;

                var sm2 = smaSeries.ToSortedMap();

                Assert.AreEqual(sm2.First, smaSeries.First);
                Assert.AreEqual(sm2.Last, smaSeries.Last);

                Assert.True(SeriesContract.MoveAtShouldWorkOnLazySeries(smaSeries));
                Assert.True(SeriesContract.ClonedCursorsAreIndependent(smaSeries));

                if (lookup == Lookup.EQ || lookup == Lookup.GE)
                {
                    var trueSma = sm.Window(10).Map(x => x.Values.Average());
                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                if (lookup == Lookup.GT)
                {
                    var trueSma = sm.Window(11).Map(x => x.Values.Average());
                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                if (lookup == Lookup.LE)
                {
                    var smaOp1  = new MAvgCount <int, double, SortedMapCursor <int, double> >(10, true);
                    var trueSma =
                        new SpanOpImpl <int,
                                        double,
                                        double,
                                        MAvgCount <int, double, SortedMapCursor <int, double> >,
                                        SortedMapCursor <int, double>
                                        >(sm.GetEnumerator(), smaOp1).Source;

                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                if (lookup == Lookup.LT)
                {
                    var smaOp1  = new MAvgCount <int, double, SortedMapCursor <int, double> >(9, true);
                    var trueSma =
                        new SpanOpImpl <int,
                                        double,
                                        double,
                                        MAvgCount <int, double, SortedMapCursor <int, double> >,
                                        SortedMapCursor <int, double>
                                        >(sm.GetEnumerator(), smaOp1).Source;

                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                Debug.WriteLine("SMA");
                foreach (var keyValuePair in smaSeries)
                {
                    Debug.WriteLine($"{keyValuePair.Key} - {keyValuePair.Value}");
                }
            }
        }
コード例 #9
0
ファイル: SpanOpTests.cs プロジェクト: lulzzz/Spreads
        public void CouldCalculateSMAWithCount()
        {
            var count = 20;
            var sm    = new SortedMap <int, double>();

            for (int i = 1; i <= count; i++)
            {
                sm.Add(i, i);
            }

            DoTest(true);
            DoTest(false);

            DoTestViaSpanOpCount(true);
            DoTestViaSpanOpCount(false);

            void DoTest(bool allowIncomplete)
            {
                // TODO separate tests/cases for true/false
                var smaOp     = new MAvgCount <int, double, SortedMapCursor <int, double> >(10, allowIncomplete);
                var smaCursor =
                    new SpanOpImpl <int,
                                    double,
                                    double,
                                    MAvgCount <int, double, SortedMapCursor <int, double> >,
                                    SortedMapCursor <int, double>
                                    >(sm.GetEnumerator(), smaOp);

                // this monster type must be hidden in the same way Lag hides its implementation
                Series <int, double, SpanOpImpl <int, double, double, MAvgCount <int, double, SortedMapCursor <int, double> >, SortedMapCursor <int, double> > > smaSeries;

                smaSeries = smaCursor.Source;

                var sm2 = smaSeries.ToSortedMap();

                Assert.AreEqual(sm2.First, smaSeries.First);
                Assert.AreEqual(sm2.Last, smaSeries.Last);

                Assert.True(SeriesContract.MoveAtShouldWorkOnLazySeries(smaSeries));
                Assert.True(SeriesContract.ClonedCursorsAreIndependent(smaSeries));

                if (!allowIncomplete)
                {
                    var trueSma = sm.Window(10).Map(x => x.Values.Average());
                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                Debug.WriteLine("SMA");
                foreach (var keyValuePair in smaSeries)
                {
                    Debug.WriteLine($"{keyValuePair.Key} - {keyValuePair.Value}");
                }
            }

            void DoTestViaSpanOpCount(bool allowIncomplete)
            {
                // TODO separate tests/cases for true/false
                var onlineOp  = new SumAvgOnlineOp <int, double, SortedMapCursor <int, double> >();
                var smaOp     = new SpanOpCount <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >(10, allowIncomplete, onlineOp);
                var smaCursor =
                    new SpanOpImpl <int,
                                    double,
                                    double,
                                    SpanOpCount <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >,
                                    SortedMapCursor <int, double>
                                    >(sm.GetEnumerator(), smaOp);

                // this monster type must be hidden in the same way Lag hides its implementation
                Series <int, double, SpanOpImpl <int, double, double, SpanOpCount <int, double, double, SortedMapCursor <int, double>, SumAvgOnlineOp <int, double, SortedMapCursor <int, double> > >, SortedMapCursor <int, double> > > smaSeries;

                smaSeries = smaCursor.Source;

                var sm2 = smaSeries.ToSortedMap();

                Assert.AreEqual(sm2.First, smaSeries.First);
                Assert.AreEqual(sm2.Last, smaSeries.Last);

                Assert.True(SeriesContract.MoveAtShouldWorkOnLazySeries(smaSeries));
                Assert.True(SeriesContract.ClonedCursorsAreIndependent(smaSeries));

                if (!allowIncomplete)
                {
                    var trueSma = sm.Window(10).Map(x => x.Values.Average());
                    Assert.True(trueSma.Keys.SequenceEqual(smaSeries.Keys));
                    Assert.True(trueSma.Values.SequenceEqual(smaSeries.Values));
                }

                Debug.WriteLine("SMA");
                foreach (var keyValuePair in smaSeries)
                {
                    Debug.WriteLine($"{keyValuePair.Key} - {keyValuePair.Value}");
                }
            }
        }
コード例 #10
0
ファイル: StatTests.cs プロジェクト: wang-shun/Spreads
        public void Stat2StDevBenchmark()
        {
            var comparer = KeyComparer <int> .Default;
            var count    = 1_000_000;
            var width    = 20;
            var sm       = new SortedMap <int, double>(count, comparer);

            sm.Add(0, 0);
            for (int i = 2; i <= count; i++)
            {
                sm.Add(i, i);
            }

            // var ds1 = new Deedle.Series<int, double>(sm.Keys.ToArray(), sm.Values.ToArray());

            var sum = 0.0;

            for (int r = 0; r < 10; r++)
            {
                var sum1 = 0.0;
                using (Benchmark.Run("Stat2 Online N", count * width))
                {
                    foreach (var stat2 in sm.Stat2(width).Values)
                    {
                        sum1 += stat2.StDev;
                    }
                }
                Assert.True(sum1 != 0);

                var sum2 = 0.0;
                using (Benchmark.Run("Stat2 Online Width GE", count * width))
                {
                    foreach (var stat2 in sm.Stat2(width - 1, Lookup.GE).Values)
                    {
                        sum2 += stat2.StDev;
                    }
                }
                Assert.True(sum2 != 0);

                var sum3 = 0.0;
                using (Benchmark.Run("Stat2 Window N", count * width))
                {
                    foreach (var stat2 in sm.Window(width).Map(x => x.Stat2()).Values)
                    {
                        sum3 += stat2.StDev;
                    }
                }
                Assert.True(sum3 != 0);

                var sum4 = 0.0;
                using (Benchmark.Run("Stat2 Window Width GE", count * width))
                {
                    foreach (var stat2 in sm.Window(width - 1, Lookup.GE).Map(x => x.Stat2()).Values)
                    {
                        sum4 += stat2.StDev;
                    }
                }
                Assert.True(sum4 != 0);

                //var sum5 = 0.0;
                //using (Benchmark.Run("Deedle (online)", count * width))
                //{
                //    var deedleStDev = Deedle.Stats.movingStdDev(width, ds1);
                //    foreach (var keyValuePair in deedleStDev.Values)
                //    {
                //        sum5 += keyValuePair;
                //    }
                //}
                //Assert.True(sum5 != 0);

                Assert.True(Math.Abs(sum1 / sum2 - 1) < 0.000001);
                Assert.True(Math.Abs(sum1 / sum3 - 1) < 0.000001);
                Assert.True(Math.Abs(sum1 / sum4 - 1) < 0.000001);
                // Assert.True(Math.Abs(sum1 / sum5 - 1) < 0.000001);

                sum = 0.0;
                using (Benchmark.Run("SortedMap enumeration", count))
                {
                    var cursor = sm.GetEnumerator();
                    while (cursor.MoveNext())
                    {
                        sum += cursor.CurrentValue;
                    }
                }
                Assert.True(sum != 0);
            }

            Benchmark.Dump($"The window width is {width}. Stat2 MOPS are calculated as a number of calculated values multiplied by width, " +
                           $"which is equivalent to the total number of cursor moves for Window case. SortedMap line is for reference - it is the " +
                           $"speed of raw iteration over SM without Stat2/Windows overheads (and not multiplied by width).");
        }