public void DoesNotConsolidateDifferentSymbols() { var consolidator = new TickQuoteBarConsolidator(2); var reference = DateTime.Today; var tick1 = new Tick { Symbol = Symbols.AAPL, Time = reference, BidPrice = 1000, BidSize = 20, TickType = TickType.Quote, }; var tick2 = new Tick { Symbol = Symbols.ZNGA, Time = reference, BidPrice = 20, BidSize = 30, TickType = TickType.Quote, }; consolidator.Update(tick1); Exception ex = Assert.Throws <InvalidOperationException>(() => consolidator.Update(tick2)); Assert.IsTrue(ex.Message.Contains("is not the same")); }
public void LastCloseAndCurrentOpenPriceShouldBeSameConsolidatedOnCount() { QuoteBar quoteBar = null; var creator = new TickQuoteBarConsolidator(2); creator.DataConsolidated += (sender, args) => { quoteBar = args; }; var reference = DateTime.Today; var tick1 = new Tick { Symbol = Symbols.SPY, Time = reference, TickType = TickType.Quote, AskPrice = 0, BidPrice = 24, }; creator.Update(tick1); var tick2 = new Tick { Symbol = Symbols.SPY, Time = reference, TickType = TickType.Quote, AskPrice = 25, BidPrice = 0, }; creator.Update(tick2); // bar 1 emitted Assert.AreEqual(tick2.AskPrice, quoteBar.Ask.Open); Assert.AreEqual(tick1.BidPrice, quoteBar.Bid.Open); Assert.AreEqual(tick2.AskPrice, quoteBar.Ask.Close); Assert.AreEqual(tick1.BidPrice, quoteBar.Bid.Close); var tick3 = new Tick { Symbol = Symbols.SPY, Time = reference.AddSeconds(1), TickType = TickType.Quote, AskPrice = 36, BidPrice = 35, }; creator.Update(tick3); creator.Update(tick3); // bar 2 emitted // ask is from tick 2 Assert.AreEqual(tick2.AskPrice, quoteBar.Ask.Open, "Ask Open not equal to Previous Close"); // bid is from tick 1 Assert.AreEqual(tick1.BidPrice, quoteBar.Bid.Open, "Bid Open not equal to Previous Close"); Assert.AreEqual(tick3.AskPrice, quoteBar.Ask.Close, "Ask Close incorrect"); Assert.AreEqual(tick3.BidPrice, quoteBar.Bid.Close, "Bid Close incorrect"); }
public QuoteTickAggregator(Resolution resolution) : base(resolution) { Consolidated = new List <BaseData>(); Consolidator = new TickQuoteBarConsolidator(resolution.ToTimeSpan()); Consolidator.DataConsolidated += (sender, consolidated) => { Consolidated.Add(consolidated as QuoteBar); }; }
public KaikoQuoteDataAggregator(Resolution resolution) { Resolution = resolution; Consolidated = new List <BaseData>(); _consolidator = new TickQuoteBarConsolidator(resolution.ToTimeSpan()); _consolidator.DataConsolidated += (sender, consolidated) => { Consolidated.Add(consolidated); }; }
/// <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 AggregatesTickToCalendarQuoteBarProperly() { // Monday var reference = new DateTime(2019, 3, 18); var ticks = new List <Tick> { new Tick(reference.AddDays(1), Symbols.EURUSD, 9, 11, 8) { Quantity = 10 }, new Tick(reference.AddDays(3), Symbols.EURUSD, 10, 12, 8) { Quantity = 10 }, new Tick(reference.AddDays(5), Symbols.EURUSD, 11, 13, 9) { Quantity = 10 }, new Tick(reference.AddDays(7), Symbols.EURUSD, 11, 13, 9) { Quantity = 10 }, new Tick(reference.AddDays(14), Symbols.EURUSD, 11, 13, 9) { Quantity = 10 } }; var weeklyConsolidator = new TickQuoteBarConsolidator(CalendarType.Weekly); weeklyConsolidator.DataConsolidated += (s, e) => { AssertTickQuoteBar( ticks.Take(3), reference, reference.AddDays(7), Symbols.EURUSD, e); }; var monthlyConsolidator = new TickQuoteBarConsolidator(CalendarType.Monthly); monthlyConsolidator.DataConsolidated += (s, e) => { AssertTickQuoteBar( ticks.Take(4), new DateTime(reference.Year, reference.Month, 1), new DateTime(reference.Year, reference.Month + 1, 1), Symbols.EURUSD, e); }; foreach (var tick in ticks.Take(4)) { weeklyConsolidator.Update(tick); } foreach (var tick in ticks) { monthlyConsolidator.Update(tick); } }
public void AggregatesNewQuoteBarProperly() { QuoteBar quoteBar = null; var creator = new TickQuoteBarConsolidator(4); creator.DataConsolidated += (sender, args) => { quoteBar = args; }; var reference = DateTime.Today; var tick1 = new Tick { Symbol = Symbols.SPY, Time = reference, BidPrice = 10, BidSize = 20, TickType = TickType.Quote }; creator.Update(tick1); Assert.IsNull(quoteBar); var tick2 = new Tick { Symbol = Symbols.SPY, Time = reference.AddHours(1), AskPrice = 20, AskSize = 10, TickType = TickType.Quote }; var badTick = new Tick { Symbol = Symbols.SPY, Time = reference.AddHours(1), AskPrice = 25, AskSize = 100, BidPrice = -100, BidSize = 2, Value = 50, Quantity = 1234, TickType = TickType.Trade }; creator.Update(badTick); Assert.IsNull(quoteBar); creator.Update(tick2); Assert.IsNull(quoteBar); var tick3 = new Tick { Symbol = Symbols.SPY, Time = reference.AddHours(2), BidPrice = 12, BidSize = 50, TickType = TickType.Quote }; creator.Update(tick3); Assert.IsNull(quoteBar); var tick4 = new Tick { Symbol = Symbols.SPY, Time = reference.AddHours(3), AskPrice = 17, AskSize = 15, TickType = TickType.Quote }; creator.Update(tick4); 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 AggregatesNewQuoteBarProperly() { QuoteBar quoteBar = null; var creator = new TickQuoteBarConsolidator(4); creator.DataConsolidated += (sender, args) => { quoteBar = args; }; var reference = DateTime.Today; var tick1 = new Tick { Symbol = Symbols.SPY, Time = reference, BidPrice = 10, BidSize = 20, TickType = TickType.Quote }; creator.Update(tick1); Assert.IsNull(quoteBar); var tick2 = new Tick { Symbol = Symbols.SPY, Time = reference.AddHours(1), AskPrice = 20, AskSize = 10, TickType = TickType.Quote }; var badTick = new Tick { Symbol = Symbols.SPY, Time = reference.AddHours(1), AskPrice = 25, AskSize = 100, BidPrice = -100, BidSize = 2, Value = 50, Quantity = 1234, TickType = TickType.Trade }; creator.Update(badTick); Assert.IsNull(quoteBar); creator.Update(tick2); Assert.IsNull(quoteBar); var tick3 = new Tick { Symbol = Symbols.SPY, Time = reference.AddHours(2), BidPrice = 12, BidSize = 50, TickType = TickType.Quote }; creator.Update(tick3); Assert.IsNull(quoteBar); var tick4 = new Tick { Symbol = Symbols.SPY, Time = reference.AddHours(3), AskPrice = 17, AskSize = 15, TickType = TickType.Quote }; creator.Update(tick4); Assert.IsNotNull(quoteBar); Assert.AreEqual(Symbols.SPY, quoteBar.Symbol); Assert.AreEqual(tick1.Time, quoteBar.Time); 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 LastCloseAndCurrentOpenPriceShouldBeSameConsolidatedOnTimeSpan() { QuoteBar quoteBar = null; var creator = new TickQuoteBarConsolidator(TimeSpan.FromMinutes(1)); creator.DataConsolidated += (sender, args) => { quoteBar = args; }; var reference = DateTime.Today; // timeframe 1 var tick1 = new Tick { Symbol = Symbols.SPY, Time = reference, TickType = TickType.Quote, AskPrice = 25, BidPrice = 24, }; creator.Update(tick1); var tick2 = new Tick { Symbol = Symbols.SPY, Time = reference.AddSeconds(1), TickType = TickType.Quote, AskPrice = 26, BidPrice = 0, }; creator.Update(tick2); var tick3 = new Tick { Symbol = Symbols.SPY, Time = reference.AddSeconds(1), TickType = TickType.Quote, AskPrice = 0, BidPrice = 25, }; creator.Update(tick3); // timeframe 2 var tick4 = new Tick { Symbol = Symbols.SPY, Time = reference.AddMinutes(1), TickType = TickType.Quote, AskPrice = 36, BidPrice = 35, }; creator.Update(tick4); //force the consolidator to emit DataConsolidated creator.Scan(reference.AddMinutes(2)); // bid is from tick 2 Assert.AreEqual(tick2.AskPrice, quoteBar.Ask.Open, "Ask Open not equal to Previous Close"); // bid is from tick 3 Assert.AreEqual(tick3.BidPrice, quoteBar.Bid.Open, "Bid Open not equal to Previous Close"); Assert.AreEqual(tick4.AskPrice, quoteBar.Ask.Close, "Ask Close incorrect"); Assert.AreEqual(tick4.BidPrice, quoteBar.Bid.Close, "Bid Close incorrect"); }