public void CalculateEquityCurve()
        {
            var deals = new List<MarketOrder>();

            var dealsOpen = TestDataGenerator.GetOpenPosition().Select(LinqToEntity.DecorateOrder).ToList();
            var dealsClose = TestDataGenerator.GetClosePosition().Select(LinqToEntity.DecorateOrder).ToList();

            deals.AddRange(dealsOpen);
            deals.AddRange(dealsClose);

            var transfers = TestDataGenerator.GetBalanceChange().Select(LinqToEntity.DecorateBalanceChange).ToList();
            var firstDealOpenedTime = deals.Min(d => d.TimeEnter);
            transfers.Insert(0, new BalanceChange
                {
                    AccountID = deals[0].AccountID,
                    ValueDate = firstDealOpenedTime.AddHours(-1),
                    CurrencyToDepoRate = 1,
                    ChangeType = BalanceChangeType.Deposit,
                    Amount = 500000
                });

            var dicQuote = new Dictionary<string, List<QuoteData>>();

            foreach (var smb in DalSpot.Instance.GetTickerNames())
                dicQuote.Add(smb, dailyQuoteStorage.GetQuotes(smb).Select(q => new QuoteData(q.b, q.b, q.a)).ToList());

            var quoteArc = new QuoteArchive(dicQuote);
            var res = curveCalculator.CalculateEquityCurve(deals, DepoCurrency, quoteArc, transfers);

            // сверить точку кривой доходности
            CheckEquityCurvePoint(res, transfers, dealsOpen, dealsClose, quoteArc, dicQuote, 0);
            CheckEquityCurvePoint(res, transfers, dealsOpen, dealsClose, quoteArc, dicQuote, 10);
            CheckEquityCurvePoint(res, transfers, dealsOpen, dealsClose, quoteArc, dicQuote, 40);
        }
Example #2
0
        public void Can_get_lots_of_records_with_new_instantiation_every_time_test()
        {
            var times = new List<double>();

            for (int i = 0; i < 40; ++i)
            {
                var sw = Stopwatch.StartNew();
                var efDriver = new EFDriver();
                var rows = efDriver.GetLotsOfRecords();

                Assert.That(rows, Is.Not.Null);
                Assert.That(rows.Count(), Is.GreaterThan(0));

                sw.Stop();

                times.Add(sw.ElapsedMilliseconds);
                Console.WriteLine("took {0} ms to get {1} records",
                    sw.ElapsedMilliseconds,
                    rows.Count());
            }

            Console.WriteLine("average: {0}, min: {1}, max: {2}, std dev: {3}",
                times.Average(),
                times.Min(),
                times.Max(),
                times.StandardDeviation());
        }
        public void Can_get_lots_of_records_with_new_instantiation_every_time_test()
        {
            var times = new List<double>();

            for (int i = 0; i < 40; ++i)
            {
                var sw = Stopwatch.StartNew();
                var dapperDriver = new DapperDriver();
                var rows = dapperDriver.GetLotsOfRecords<TransactionHistory>();

                Assert.That(rows, Is.Not.Null);
                Assert.That(rows.Count(), Is.GreaterThan(0));

                sw.Stop();

                times.Add(sw.ElapsedMilliseconds);
                Console.WriteLine("took {0} ms to get {1} records",
                    sw.ElapsedMilliseconds,
                    rows.Count());
            }

            Console.WriteLine("average: {0}, min: {1}, max: {2}",
                times.Average(),
                times.Min(),
                times.Max());

            var timesSansMinAndMax = new List<double>();
            timesSansMinAndMax.AddRange(times);
            timesSansMinAndMax.Remove(timesSansMinAndMax.Min());
            timesSansMinAndMax.Remove(timesSansMinAndMax.Max());
            Console.WriteLine("average sans min & max: {0}",
                timesSansMinAndMax.Average());
        }
Example #4
0
        public void Can_get_few_records_test()
        {
            var efDriver = new EFDriver();
            var times = new List<double>();

            for (int i = 0; i < 100; ++i)
            {
                var sw = Stopwatch.StartNew();
                var rows = efDriver.GetAFewRecords();

                Assert.That(rows, Is.Not.Null);
                Assert.That(rows.Count(), Is.GreaterThan(0));

                sw.Stop();

                times.Add(sw.ElapsedMilliseconds);
                Console.WriteLine("took {0} ms to get {1} records",
                    sw.ElapsedMilliseconds,
                    rows.Count());
            }

            Console.WriteLine("average: {0}, min: {1}, max: {2}, std dev: {3}, median: {4}",
                times.Average(),
                times.Min(),
                times.Max(),
                times.StandardDeviation(),
                times.Median());

            var timesSansMinAndMax = new List<double>();
            timesSansMinAndMax.AddRange(times);
            timesSansMinAndMax.Remove(timesSansMinAndMax.Min());
            timesSansMinAndMax.Remove(timesSansMinAndMax.Max());
            Console.WriteLine("average sans min & max: {0}",
                timesSansMinAndMax.Average());
        }
        public void AggregatesTicksIntoSecondBars()
        {
            var timeProvider = new ManualTimeProvider(TimeZones.NewYork);
            var enumerator = new TradeBarBuilderEnumerator(Time.OneSecond, TimeZones.NewYork, timeProvider);

            // noon new york time
            var currentTime = new DateTime(2015, 10, 08, 12, 0, 0);
            timeProvider.SetCurrentTime(currentTime);

            // add some ticks
            var ticks = new List<Tick>
            {
                new Tick(currentTime, "SPY", 199.55m, 199, 200) {Quantity = 10},
                new Tick(currentTime, "SPY", 199.56m, 199.21m, 200.02m) {Quantity = 5},
                new Tick(currentTime, "SPY", 199.53m, 198.77m, 199.75m) {Quantity = 20},
                new Tick(currentTime, "SPY", 198.77m, 199.75m) {Quantity = 0},
                new Tick(currentTime, "SPY", 199.73m, 198.77m, 199.75m) {Quantity = 20},
                new Tick(currentTime, "SPY", 198.77m, 199.75m) {Quantity = 0},
            };

            foreach (var tick in ticks)
            {
                enumerator.ProcessData(tick);
            }

            // even though no data is here, it will still return true
            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNull(enumerator.Current);

            // advance a second
            currentTime = currentTime.AddSeconds(1);
            timeProvider.SetCurrentTime(currentTime);

            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNotNull(enumerator.Current);

            // in the spirit of not duplicating the above code 5 times (OHLCV, we'll assert these ere as well)
            var bar = (TradeBar)enumerator.Current;
            Assert.AreEqual(currentTime.AddSeconds(-1), bar.Time);
            Assert.AreEqual(currentTime, bar.EndTime);
            Assert.AreEqual("SPY", bar.Symbol.Value);
            Assert.AreEqual(ticks.First().LastPrice, bar.Open);
            Assert.AreEqual(ticks.Max(x => x.LastPrice), bar.High);
            Assert.AreEqual(ticks.Min(x => x.LastPrice), bar.Low);
            Assert.AreEqual(ticks.Last().LastPrice, bar.Close);
            Assert.AreEqual(ticks.Sum(x => x.Quantity), bar.Volume);
        }
		public void Can_GetSetCountByScores()
		{
			var scores = new List<double>();

			storeMembers.ForEach(x =>
			{ 
				Redis.AddItemToSortedSet(SetId, x);
				scores.Add(RedisClient.GetLexicalScore(x));
			});

			Assert.That(Redis.GetSortedSetCount(SetId, scores.Min(), scores.Max()), Is.EqualTo(storeMembers.Count()));
			Assert.That(Redis.GetSortedSetCount(SetId, scores.Min(), scores.Min()), Is.EqualTo(1));
		}
Example #7
0
        public void Can_get_scalar_value()
        {
            List<Author> authors = new List<Author>();
            authors.Add(new Author() { Name = "Demis Bellot", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 99.9m, Comments = "CSharp books", Rate = 10, City = "London", FloatProperty = 10.25f, DoubleProperty = 3.23 });
            authors.Add(new Author() { Name = "Angel Colmenares", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 50.0m, Comments = "CSharp books", Rate = 5, City = "Bogota", FloatProperty = 7.59f, DoubleProperty = 4.23 });
            authors.Add(new Author() { Name = "Adam Witco", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 80.0m, Comments = "Math Books", Rate = 9, City = "London", FloatProperty = 15.5f, DoubleProperty = 5.42 });
            authors.Add(new Author() { Name = "Claudia Espinel", Birthday = DateTime.Today.AddYears(-23), Active = true, Earnings = 60.0m, Comments = "Cooking books", Rate = 10, City = "Bogota", FloatProperty = 0.57f, DoubleProperty = 8.76 });
            authors.Add(new Author() { Name = "Libardo Pajaro", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 80.0m, Comments = "CSharp books", Rate = 9, City = "Bogota", FloatProperty = 8.43f, DoubleProperty = 7.35 });
            authors.Add(new Author() { Name = "Jorge Garzon", Birthday = DateTime.Today.AddYears(-28), Active = true, Earnings = 70.0m, Comments = "CSharp books", Rate = 9, City = "Bogota", FloatProperty = 1.25f, DoubleProperty = 0.3652 });
            authors.Add(new Author() { Name = "Alejandro Isaza", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 70.0m, Comments = "Java books", Rate = 0, City = "Bogota", FloatProperty = 1.5f, DoubleProperty = 100.563 });
            authors.Add(new Author() { Name = "Wilmer Agamez", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 30.0m, Comments = "Java books", Rate = 0, City = "Cartagena", FloatProperty = 3.5f, DoubleProperty = 7.23 });
            authors.Add(new Author() { Name = "Rodger Contreras", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 90.0m, Comments = "CSharp books", Rate = 8, City = "Cartagena", FloatProperty = 0.25f, DoubleProperty = 9.23 });
            authors.Add(new Author() { Name = "Chuck Benedict", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "CSharp books", Rate = 8, City = "London", FloatProperty = 9.95f, DoubleProperty = 4.91 });
            authors.Add(new Author() { Name = "James Benedict II", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "Java books", Rate = 5, City = "Berlin", FloatProperty = 4.44f, DoubleProperty = 6.41 });
            authors.Add(new Author() { Name = "Ethan Brown", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 45.0m, Comments = "CSharp books", Rate = 5, City = "Madrid", FloatProperty = 6.67f, DoubleProperty = 8.05 });
            authors.Add(new Author() { Name = "Xavi Garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 75.0m, Comments = "CSharp books", Rate = 9, City = "Madrid", FloatProperty = 1.25f, DoubleProperty = 3.99 });
            authors.Add(new Author()
            {
                Name = "Luis garzon",
                Birthday = DateTime.Today.AddYears(-22),
                Active = true,
                Earnings = 85.0m,
                Comments = "CSharp books",
                Rate = 10,
                City = "Mexico",
                LastActivity = DateTime.Today,
                NRate = 5,
                FloatProperty = 1.25f,
                NFloatProperty = 3.15f,
                DoubleProperty = 1.25,
                NDoubleProperty = 8.25
            });

            using (var db = OpenDbConnection())
            {
                db.CreateTable<Author>(true);
                db.DeleteAll<Author>();

                db.InsertAll(authors);

                var expectedDate = authors.Max(e => e.Birthday);
                var r1 = db.Scalar<Author, DateTime>(e => Sql.Max(e.Birthday));
                Assert.That(expectedDate, Is.EqualTo(r1));

                expectedDate = authors.Where(e => e.City == "London").Max(e => e.Birthday);
                r1 = db.Scalar<Author, DateTime>(e => Sql.Max(e.Birthday), e => e.City == "London");
                Assert.That(expectedDate, Is.EqualTo(r1));

                r1 = db.Scalar<Author, DateTime>(e => Sql.Max(e.Birthday), e => e.City == "SinCity");
                Assert.That(default(DateTime), Is.EqualTo(r1));


                var expectedNullableDate = authors.Max(e => e.LastActivity);
                DateTime? r2 = db.Scalar<Author, DateTime?>(e => Sql.Max(e.LastActivity));
                Assert.That(expectedNullableDate, Is.EqualTo(r2));

                expectedNullableDate = authors.Where(e => e.City == "Bogota").Max(e => e.LastActivity);
                r2 = db.Scalar<Author, DateTime?>(
                    e => Sql.Max(e.LastActivity),
                    e => e.City == "Bogota");
                Assert.That(r2, Is.EqualTo(expectedNullableDate));

                r2 = db.Scalar<Author, DateTime?>(e => Sql.Max(e.LastActivity), e => e.City == "SinCity");
                Assert.That(default(DateTime?), Is.EqualTo(r2));


                var expectedDecimal = authors.Max(e => e.Earnings);
                decimal r3 = db.Scalar<Author, decimal>(e => Sql.Max(e.Earnings));
                Assert.That(expectedDecimal, Is.EqualTo(r3));

                expectedDecimal = authors.Where(e => e.City == "London").Max(e => e.Earnings);
                r3 = db.Scalar<Author, decimal>(e => Sql.Max(e.Earnings), e => e.City == "London");
                Assert.That(expectedDecimal, Is.EqualTo(r3));

                r3 = db.Scalar<Author, decimal>(e => Sql.Max(e.Earnings), e => e.City == "SinCity");
                Assert.That(default(decimal), Is.EqualTo(r3));


                var expectedNullableDecimal = authors.Max(e => e.NEarnings);
                decimal? r4 = db.Scalar<Author, decimal?>(e => Sql.Max(e.NEarnings));
                Assert.That(expectedNullableDecimal, Is.EqualTo(r4));

                expectedNullableDecimal = authors.Where(e => e.City == "London").Max(e => e.NEarnings);
                r4 = db.Scalar<Author, decimal?>(e => Sql.Max(e.NEarnings), e => e.City == "London");
                Assert.That(expectedNullableDecimal, Is.EqualTo(r4));

                r4 = db.Scalar<Author, decimal?>(e => Sql.Max(e.NEarnings), e => e.City == "SinCity");
                Assert.That(default(decimal?), Is.EqualTo(r4));


                var expectedDouble = authors.Max(e => e.DoubleProperty);
                double r5 = db.Scalar<Author, double>(e => Sql.Max(e.DoubleProperty));
                Assert.That(expectedDouble, Is.EqualTo(r5).Within(.1d));

                expectedDouble = authors.Where(e => e.City == "London").Max(e => e.DoubleProperty);
                r5 = db.Scalar<Author, double>(e => Sql.Max(e.DoubleProperty), e => e.City == "London");
                Assert.That(expectedDouble, Is.EqualTo(r5).Within(.1d));

                r5 = db.Scalar<Author, double>(e => Sql.Max(e.DoubleProperty), e => e.City == "SinCity");
                Assert.That(default(double), Is.EqualTo(r5));


                var expectedNullableDouble = authors.Max(e => e.NDoubleProperty);
                double? r6 = db.Scalar<Author, double?>(e => Sql.Max(e.NDoubleProperty));
                Assert.That(expectedNullableDouble, Is.EqualTo(r6));


                expectedNullableDouble = authors.Where(e => e.City == "London").Max(e => e.NDoubleProperty);
                r6 = db.Scalar<Author, double?>(e => Sql.Max(e.NDoubleProperty), e => e.City == "London");
                Assert.That(expectedNullableDouble, Is.EqualTo(r6));

                r6 = db.Scalar<Author, double?>(e => Sql.Max(e.NDoubleProperty), e => e.City == "SinCity");
                Assert.That(default(double?), Is.EqualTo(r6));



                var expectedFloat = authors.Max(e => e.FloatProperty);
                var r7 = db.Scalar<Author, float>(e => Sql.Max(e.FloatProperty));
                Assert.That(expectedFloat, Is.EqualTo(r7));

                expectedFloat = authors.Where(e => e.City == "London").Max(e => e.FloatProperty);
                r7 = db.Scalar<Author, float>(e => Sql.Max(e.FloatProperty), e => e.City == "London");
                Assert.That(expectedFloat, Is.EqualTo(r7));

                r7 = db.Scalar<Author, float>(e => Sql.Max(e.FloatProperty), e => e.City == "SinCity");
                Assert.That(default(float), Is.EqualTo(r7));


                var expectedNullableFloat = authors.Max(e => e.NFloatProperty);
                var r8 = db.Scalar<Author, float?>(e => Sql.Max(e.NFloatProperty));
                Assert.That(expectedNullableFloat, Is.EqualTo(r8));

                expectedNullableFloat = authors.Where(e => e.City == "London").Max(e => e.NFloatProperty);
                r8 = db.Scalar<Author, float?>(e => Sql.Max(e.NFloatProperty), e => e.City == "London");
                Assert.That(expectedNullableFloat, Is.EqualTo(r8));

                r8 = db.Scalar<Author, float?>(e => Sql.Max(e.NFloatProperty), e => e.City == "SinCity");
                Assert.That(default(float?), Is.EqualTo(r8));


                var expectedString = authors.Min(e => e.Name);
                var r9 = db.Scalar<Author, string>(e => Sql.Min(e.Name));
                Assert.That(expectedString, Is.EqualTo(r9));

                expectedString = authors.Where(e => e.City == "London").Min(e => e.Name);
                r9 = db.Scalar<Author, string>(e => Sql.Min(e.Name), e => e.City == "London");
                Assert.That(expectedString, Is.EqualTo(r9));

                r9 = db.Scalar<Author, string>(e => Sql.Max(e.Name), e => e.City == "SinCity");
                Assert.That(string.IsNullOrEmpty(r9));

                //Can't MIN(bit)/MAX(bit) in SQL Server
                if (Dialect == Dialect.SqlServer)
                {
                    var expectedBool = authors.Min(e => e.Active);
                    var r10 = db.Scalar<Author, bool>(e => Sql.Count(e.Active));
                    Assert.That(expectedBool, Is.EqualTo(r10));

                    expectedBool = authors.Max(e => e.Active);
                    r10 = db.Scalar<Author, bool>(e => Sql.Count(e.Active));
                    Assert.That(expectedBool, Is.EqualTo(r10));

                    r10 = db.Scalar<Author, bool>(e => Sql.Count(e.Active), e => e.City == "SinCity");
                    Assert.IsFalse(r10);
                }

                var expectedShort = authors.Max(e => e.Rate);
                var r11 = db.Scalar<Author, short>(e => Sql.Max(e.Rate));
                Assert.That(expectedShort, Is.EqualTo(r11));

                expectedShort = authors.Where(e => e.City == "London").Max(e => e.Rate);
                r11 = db.Scalar<Author, short>(e => Sql.Max(e.Rate), e => e.City == "London");
                Assert.That(expectedShort, Is.EqualTo(r11));

                r11 = db.Scalar<Author, short>(e => Sql.Max(e.Rate), e => e.City == "SinCity");
                Assert.That(default(short), Is.EqualTo(r7));


                var expectedNullableShort = authors.Max(e => e.NRate);
                var r12 = db.Scalar<Author, short?>(e => Sql.Max(e.NRate));
                Assert.That(expectedNullableShort, Is.EqualTo(r12));

                expectedNullableShort = authors.Where(e => e.City == "London").Max(e => e.NRate);
                r12 = db.Scalar<Author, short?>(e => Sql.Max(e.NRate), e => e.City == "London");
                Assert.That(expectedNullableShort, Is.EqualTo(r12));

                r12 = db.Scalar<Author, short?>(e => Sql.Max(e.NRate), e => e.City == "SinCity");
                Assert.That(default(short?), Is.EqualTo(r12));

            }

        }
Example #8
0
 public static double IntersectBox(Box box, Ray ray)
 {
     Ball ball = GetExternalSphere(box);
     if (double.IsPositiveInfinity(IntersectBall(ball, ray)))
         return double.PositiveInfinity;
     else
     {
         var points = new List<Point3D>();
         var vertex = GetVertex(box);
         int[][] order = new int[12][];
         order[0] = new[] {0, 2, 1};
         order[1] = new[] {1, 2, 4};
         order[2] = new[] {0, 5, 2};
         order[3] = new[] {0, 3, 5};
         order[4] = new[] {0, 3, 1};
         order[5] = new[] {1, 3, 6};
         order[6] = new[] {3, 5, 6};
         order[7] = new[] {6, 5, 7};
         order[8] = new[] {1, 6, 7};
         order[9] = new[] {1, 7, 4};
         order[10] = new[] {2, 5, 7};
         order[11] = new[] {2, 7, 4};
         for (int i = 0; i < 12; i++)
         {
             Point3D? point = TriangleIntersection.IntersectTriangle(vertex[order[i][0]], vertex[order[i][1]],
                                                                     vertex[order[i][2]], ray);
             if (point != null)
                 points.Add(point.Value);
             else 
             {
                 point = TriangleIntersection.IntersectTriangle(vertex[order[i][0]], vertex[order[i][2]],
                                                                     vertex[order[i][1]], ray);
                 if (point != null)
                     points.Add(point.Value);
             }
         }
         if (points.Capacity == 0)
         {
             return double.PositiveInfinity;
         }
         return points.Min(a => ray.Origin.Hypot(a));
     }
 }
Example #9
0
		public void BenchSingleAdd()
		{
			Database.RegisterDataObject(typeof(TestTable));
			Database.RegisterDataObject(typeof(TestTableRelations));
			Database.RegisterDataObject(typeof(TestTableRelationsEntries));

			Database.DeleteObject(Database.SelectAllObjects<TestTable>());
			Database.DeleteObject(Database.SelectAllObjects<TestTableRelations>());
			Database.DeleteObject(Database.SelectAllObjects<TestTableRelationsEntries>());
			
			Assert.IsEmpty(Database.SelectAllObjects<TestTable>(), "Database shouldn't have any record For TestTable.");
			Assert.IsEmpty(Database.SelectAllObjects<TestTableRelations>(), "Database shouldn't have any record For TestTable.");
			Assert.IsEmpty(Database.SelectAllObjects<TestTableRelationsEntries>(), "Database shouldn't have any record For TestTable.");
			
			var objs = Enumerable.Range(0, 100).Select(i => new TestTable { TestField = string.Format("Bench Single Add '{0}'", i) }).ToArray();

			var times = new List<long>();
			foreach (var obj in objs)
			{
				var stopWatch = Stopwatch.StartNew();
				Database.AddObject(obj);
				stopWatch.Stop();
				times.Add(stopWatch.ElapsedMilliseconds);
			}
						
			var relationObjs = Enumerable.Range(0, 100).Select(i => new TestTableRelations { TestField = string.Format("Bench Single Relations Add '{0}'", i) }).ToArray();
			foreach (var obj in relationObjs)
				obj.Entries = Enumerable.Range(0, 5).Select(i => new TestTableRelationsEntries { ForeignTestField = obj.ObjectId }).ToArray();
			
			var timesRelations =  new List<long>();
			foreach (var obj in relationObjs)
			{
				var stopWatch = Stopwatch.StartNew();
				Database.AddObject(obj);
				stopWatch.Stop();
				timesRelations.Add(stopWatch.ElapsedMilliseconds);
			}

			Console.WriteLine("Bench Single TestTable Add Total Elapse {3}ms, Average {0}ms, Min {1}ms, Max {2}ms", times.Average(), times.Min(), times.Max(), times.Sum());
			Console.WriteLine("Bench Single TestTableRelations Add Total Elapse {3}ms, Average {0}ms, Min {1}ms, Max {2}ms", timesRelations.Average(), timesRelations.Min(), timesRelations.Max(), timesRelations.Sum());
		}
Example #10
0
        public void ListExtensions_Min_ThrowsExceptionIfListIsEmpty()
        {
            var list = new List<Int32>();

            Assert.That(() => list.Min(),
                Throws.TypeOf<InvalidOperationException>());
        }
Example #11
0
        public void ListExtensions_Min_ReturnsMinValue()
        {
            var list = new List<Int32>() { 4, 5, 6, 99, 10, 1, 12, 45 };

            var result = list.Min();

            TheResultingValue(result).ShouldBe(1);
        }
        public void maximum_inflight_is_respected(int limit)
        {
            var counts = new List<int>();
            long completed = 0;
            var _lock = new object();

            // ReSharper disable AccessToModifiedClosure
            _subject.AddConsumer(s => {
                Thread.Sleep(15);
                lock (_lock) { counts.Add(_subject.CurrentInflight()); }
                Interlocked.Increment(ref completed);
                Thread.Sleep(15);
            });
            // ReSharper restore AccessToModifiedClosure

            _subject.SetMaximumInflight(limit);
            _subject.Start();

            const int runs = 100;
            for (int i = 0; i < runs; i++) { _subject.AddWork(""); }

            while (Interlocked.Read(ref completed) < runs)
            {
                Thread.Sleep(500);
            }
            _subject.Stop();

            Assert.That(counts.Count(), Is.GreaterThan(0), "No actions ran");
            Assert.That(counts.Min(), Is.GreaterThan(0), "Inflight count is invalid");
            Assert.That(counts.Max(), Is.LessThanOrEqualTo(limit), "More workers run in parallel than limit");
        }