public void NewDataAvailableShouldFire()
        {
            var currentTime = new DateTime(2000, 01, 01);
            var available   = false;
            var enumerator  = new ScannableEnumerator <Tick>(
                new IdentityDataConsolidator <Tick>(),
                DateTimeZone.ForOffset(Offset.FromHours(-5)),
                new ManualTimeProvider(currentTime),
                (s, e) => { available = true; }
                );

            // returns true even if no data present until stop is called
            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNull(enumerator.Current);
            Assert.IsFalse(available);

            var tick1 = new Tick(currentTime, Symbols.SPY, 199.55m, 199, 200)
            {
                Quantity = 10
            };

            enumerator.Update(tick1);
            Assert.IsTrue(available);

            enumerator.Dispose();
        }
示例#2
0
        /// <summary>
        /// Add new subscription to current <see cref="IDataAggregator"/> instance
        /// </summary>
        /// <param name="dataConfig">defines the parameters to subscribe to a data feed</param>
        /// <param name="newDataAvailableHandler">handler to be fired on new data available</param>
        /// <returns>The new enumerator for this subscription request</returns>
        public IEnumerator <BaseData> Add(SubscriptionDataConfig dataConfig, EventHandler newDataAvailableHandler)
        {
            IDataConsolidator consolidator;
            var period        = dataConfig.Resolution.ToTimeSpan();
            var isPeriodBased = false;

            switch (dataConfig.Type.Name)
            {
            case nameof(QuoteBar):
                isPeriodBased = dataConfig.Resolution != Resolution.Tick;
                consolidator  = new TickQuoteBarConsolidator(period);
                break;

            case nameof(TradeBar):
                isPeriodBased = dataConfig.Resolution != Resolution.Tick;
                consolidator  = new TickConsolidator(period);
                break;

            case nameof(OpenInterest):
                isPeriodBased = dataConfig.Resolution != Resolution.Tick;
                consolidator  = new OpenInterestConsolidator(period);
                break;

            case nameof(Tick):
                consolidator = FilteredIdentityDataConsolidator.ForTickType(dataConfig.TickType);
                break;

            case nameof(Split):
                consolidator = new IdentityDataConsolidator <Split>();
                break;

            case nameof(Dividend):
                consolidator = new IdentityDataConsolidator <Dividend>();
                break;

            default:
                // streaming custom data subscriptions can pass right through
                consolidator = new FilteredIdentityDataConsolidator <BaseData>(data => data.GetType() == dataConfig.Type);
                break;
            }

            var enumerator = new ScannableEnumerator <BaseData>(consolidator, dataConfig.ExchangeTimeZone, TimeProvider, newDataAvailableHandler, isPeriodBased);

            _enumerators.AddOrUpdate(
                dataConfig.Symbol.ID,
                new List <KeyValuePair <SubscriptionDataConfig, ScannableEnumerator <BaseData> > > {
                new KeyValuePair <SubscriptionDataConfig, ScannableEnumerator <BaseData> >(dataConfig, enumerator)
            },
                (k, v) => { return(v.Concat(new[] { new KeyValuePair <SubscriptionDataConfig, ScannableEnumerator <BaseData> >(dataConfig, enumerator) }).ToList()); });

            return(enumerator);
        }
        public void PassesTicksStraightThrough()
        {
            var currentTime = new DateTime(2000, 01, 01);
            var enumerator  = new ScannableEnumerator <Tick>(
                new IdentityDataConsolidator <Tick>(),
                DateTimeZone.ForOffset(Offset.FromHours(-5)),
                new ManualTimeProvider(currentTime),
                (s, e) => { }
                );

            // returns true even if no data present until stop is called
            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNull(enumerator.Current);

            var tick1 = new Tick(currentTime, Symbols.SPY, 199.55m, 199, 200)
            {
                Quantity = 10
            };

            enumerator.Update(tick1);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(tick1, enumerator.Current);

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

            var tick2 = new Tick(currentTime, Symbols.SPY, 199.56m, 199.21m, 200.02m)
            {
                Quantity = 5
            };

            enumerator.Update(tick2);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(tick2, enumerator.Current);

            enumerator.Dispose();
        }
        public void AggregatesNewQuoteBarProperly()
        {
            var reference = DateTime.Today;

            var enumerator = new ScannableEnumerator <Data.BaseData>(
                new TickQuoteBarConsolidator(4),
                DateTimeZone.ForOffset(Offset.FromHours(-5)),
                new ManualTimeProvider(reference),
                (s, e) => { }
                );

            var tick1 = new Tick
            {
                Symbol   = Symbols.SPY,
                Time     = reference,
                BidPrice = 10,
                BidSize  = 20,
                TickType = TickType.Quote
            };

            enumerator.Update(tick1);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNull(enumerator.Current);

            var tick2 = new Tick
            {
                Symbol   = Symbols.SPY,
                Time     = reference.AddMinutes(1),
                AskPrice = 20,
                AskSize  = 10,
                TickType = TickType.Quote
            };

            var badTick = new Tick
            {
                Symbol   = Symbols.SPY,
                Time     = reference.AddMinutes(1),
                AskPrice = 25,
                AskSize  = 100,
                BidPrice = -100,
                BidSize  = 2,
                Value    = 50,
                Quantity = 1234,
                TickType = TickType.Trade
            };

            enumerator.Update(badTick);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNull(enumerator.Current);

            enumerator.Update(tick2);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNull(enumerator.Current);

            var tick3 = new Tick
            {
                Symbol   = Symbols.SPY,
                Time     = reference.AddMinutes(2),
                BidPrice = 12,
                BidSize  = 50,
                TickType = TickType.Quote
            };

            enumerator.Update(tick3);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNull(enumerator.Current);

            var tick4 = new Tick
            {
                Symbol   = Symbols.SPY,
                Time     = reference.AddMinutes(3),
                AskPrice = 17,
                AskSize  = 15,
                TickType = TickType.Quote
            };

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

            QuoteBar quoteBar = enumerator.Current as QuoteBar;

            Assert.IsNotNull(quoteBar);

            Assert.AreEqual(Symbols.SPY, quoteBar.Symbol);
            Assert.AreEqual(tick1.Time, quoteBar.Time);
            Assert.AreEqual(tick4.EndTime, quoteBar.EndTime);
            Assert.AreEqual(tick1.BidPrice, quoteBar.Bid.Open);
            Assert.AreEqual(tick1.BidPrice, quoteBar.Bid.Low);
            Assert.AreEqual(tick3.BidPrice, quoteBar.Bid.High);
            Assert.AreEqual(tick3.BidPrice, quoteBar.Bid.Close);
            Assert.AreEqual(tick3.BidSize, quoteBar.LastBidSize);

            Assert.AreEqual(tick2.AskPrice, quoteBar.Ask.Open);
            Assert.AreEqual(tick4.AskPrice, quoteBar.Ask.Low);
            Assert.AreEqual(tick2.AskPrice, quoteBar.Ask.High);
            Assert.AreEqual(tick4.AskPrice, quoteBar.Ask.Close);
            Assert.AreEqual(tick4.AskSize, quoteBar.LastAskSize);
        }
        public void MoveNextScanQuoteBar()
        {
            var offset       = Offset.FromHours(-5);
            var timeZone     = DateTimeZone.ForOffset(offset);
            var utc          = new DateTimeOffset(DateTime.Today);
            var reference    = utc.ToOffset(offset.ToTimeSpan());
            var timeProvider = new ManualTimeProvider(reference.DateTime, timeZone);

            var enumerator = new ScannableEnumerator <Data.BaseData>(
                new TickQuoteBarConsolidator(TimeSpan.FromMinutes(1)),
                timeZone,
                timeProvider,
                (s, e) => { }
                );

            var tick1 = new Tick
            {
                Symbol   = Symbols.SPY,
                Time     = reference.DateTime,
                BidPrice = 10,
                BidSize  = 20,
                TickType = TickType.Quote
            };

            enumerator.Update(tick1);

            var tick2 = new Tick
            {
                Symbol   = Symbols.SPY,
                Time     = reference.DateTime.AddSeconds(1),
                AskPrice = 20,
                AskSize  = 10,
                TickType = TickType.Quote
            };

            enumerator.Update(tick2);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNull(enumerator.Current);

            var tick3 = new Tick
            {
                Symbol   = Symbols.SPY,
                Time     = reference.DateTime.AddSeconds(2),
                BidPrice = 12,
                BidSize  = 50,
                TickType = TickType.Quote
            };

            enumerator.Update(tick3);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNull(enumerator.Current);

            var tick4 = new Tick
            {
                Symbol   = Symbols.SPY,
                Time     = reference.DateTime.AddSeconds(3),
                AskPrice = 17,
                AskSize  = 15,
                TickType = TickType.Quote
            };

            enumerator.Update(tick4);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNull(enumerator.Current);

            timeProvider.SetCurrentTime(reference.DateTime.AddMinutes(2));

            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNotNull(enumerator.Current);
            QuoteBar quoteBar = enumerator.Current as QuoteBar;

            Assert.IsNotNull(quoteBar);

            Assert.AreEqual(Symbols.SPY, quoteBar.Symbol);
            Assert.AreEqual(tick1.Time, quoteBar.Time);
            Assert.AreNotEqual(tick4.EndTime, quoteBar.EndTime);
            Assert.AreEqual(tick1.BidPrice, quoteBar.Bid.Open);
            Assert.AreEqual(tick1.BidPrice, quoteBar.Bid.Low);
            Assert.AreEqual(tick3.BidPrice, quoteBar.Bid.High);
            Assert.AreEqual(tick3.BidPrice, quoteBar.Bid.Close);
            Assert.AreEqual(tick3.BidSize, quoteBar.LastBidSize);

            Assert.AreEqual(tick2.AskPrice, quoteBar.Ask.Open);
            Assert.AreEqual(tick4.AskPrice, quoteBar.Ask.Low);
            Assert.AreEqual(tick2.AskPrice, quoteBar.Ask.High);
            Assert.AreEqual(tick4.AskPrice, quoteBar.Ask.Close);
            Assert.AreEqual(tick4.AskSize, quoteBar.LastAskSize);
        }