Example #1
0
        public void NextTickTime_CreatesTimes(Resolution resolution, DataDensity density)
        {
            var count     = 100;
            var deltaSum  = TimeSpan.Zero;
            var previous  = new DateTime(2019, 01, 14, 9, 30, 0);
            var increment = resolution.ToTimeSpan();

            if (increment == TimeSpan.Zero)
            {
                increment = TimeSpan.FromMilliseconds(500);
            }

            var marketHours = MarketHoursDatabase.FromDataFolder()
                              .GetExchangeHours(_symbol.ID.Market, _symbol, _symbol.SecurityType);

            for (int i = 0; i < count; i++)
            {
                var next     = _tickGenerator.NextTickTime(previous, resolution, density);
                var barStart = next.Subtract(increment);
                Assert.Less(previous, next);
                Assert.IsTrue(marketHours.IsOpen(barStart, next, false));

                var delta = next - previous;
                deltaSum += delta;

                previous = next;
            }

            var avgDelta = TimeSpan.FromTicks(deltaSum.Ticks / count);

            switch (density)
            {
            case DataDensity.Dense:
                // more frequent than once an increment
                Assert.Less(avgDelta, increment);
                break;

            case DataDensity.Sparse:
                // less frequent that once an increment
                Assert.Greater(avgDelta, increment);
                break;

            case DataDensity.VerySparse:
                // less frequent than one every 10 increments
                Assert.Greater(avgDelta, TimeSpan.FromTicks(increment.Ticks * 10));
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(density), density, null);
            }
        }
Example #2
0
        public virtual DateTime NextTickTime(Symbol symbol, DateTime previous, Resolution resolution, DataDensity density)
        {
            var increment = resolution.ToTimeSpan();
            if (increment == TimeSpan.Zero)
            {
                increment = TimeSpan.FromMilliseconds(500);
            }

            double steps;
            switch (density)
            {
                case DataDensity.Dense:
                    steps = 0.5 * _random.NextDouble();
                    break;

                case DataDensity.Sparse:
                    steps = 5 * _random.NextDouble();
                    break;

                case DataDensity.VerySparse:
                    steps = 50 * _random.NextDouble();
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(density), density, null);
            }

            var delta = TimeSpan.FromTicks((long) (steps * increment.Ticks));
            var tickTime = previous.Add(delta);
            if (tickTime == previous)
            {
                tickTime = tickTime.Add(increment);
            }

            var barStart = tickTime.Subtract(increment);
            var marketHours = _marketHoursDatabase.GetExchangeHours(symbol.ID.Market, symbol, symbol.SecurityType);
            if (!marketHours.IsDateOpen(tickTime) || !marketHours.IsOpen(barStart, tickTime, false))
            {
                // we ended up outside of market hours, emit a new tick at market open
                var nextMarketOpen = marketHours.GetNextMarketOpen(tickTime, false);
                if (resolution == Resolution.Tick)
                {
                    resolution = Resolution.Second;
                }

                // emit a new tick somewhere in the next trading day at a step higher resolution to guarantee a hit
                return NextTickTime(symbol, nextMarketOpen, resolution - 1, density);
            }

            return tickTime;
        }