using System; using System.Collections.Generic; using System.Linq; using QuantConnect.Data; using QuantConnect.Data.Consolidators; using QuantConnect.Data.Market; using QuantConnect.Util; namespace QuantConnect.ToolBox { /// /// Class that uses consolidators to aggregate tick data data /// public abstract class TickAggregator { protected TickAggregator(Resolution resolution, TickType tickType) { TickType = tickType; Resolution = resolution; } /// /// Gets the tick type of the consolidator /// public TickType TickType { get; protected set; } /// /// The consolidator used to aggregate data from /// higher resolutions to data in lower resolutions /// public IDataConsolidator Consolidator { get; protected set; } /// /// The consolidated data /// public List Consolidated { get; protected set; } /// /// The resolution that the data is being aggregated into /// public Resolution Resolution { get; } /// /// Updates the consolidator with the specified bar. /// /// The latest data observation. public virtual void Update(BaseData data) { Consolidator.Update(data); } /// /// Return all the consolidated data as well as the /// bar the consolidator is currently working on /// public List Flush() { var data = new List(Consolidated); if (Consolidator.WorkingData != null) { data.Add(Consolidator.WorkingData as BaseData); } return data; } /// /// Creates the correct instances for the specified tick types and resolution. /// will ignore and use /// public static IEnumerable ForTickTypes(SecurityType securityType, Resolution resolution, params TickType[] tickTypes) { if (resolution == Resolution.Tick) { foreach (var tickType in tickTypes.Where(t => LeanData.IsValidConfiguration(securityType, resolution, t))) { // OI is special if (tickType == TickType.OpenInterest) { yield return new OpenInterestTickAggregator(resolution); continue; } yield return new IdentityTickAggregator(tickType); } yield break; } foreach (var tickType in tickTypes.Where(t => LeanData.IsValidConfiguration(securityType, resolution, t))) { switch (tickType) { case TickType.Trade: yield return new TradeTickAggregator(resolution); break; case TickType.Quote: yield return new QuoteTickAggregator(resolution); break; case TickType.OpenInterest: yield return new OpenInterestTickAggregator(resolution); break; default: throw new ArgumentOutOfRangeException(nameof(tickType), tickType, null); } } } } /// /// Use to consolidate quote ticks into a specified resolution /// public class QuoteTickAggregator : TickAggregator { public QuoteTickAggregator(Resolution resolution) : base(resolution, TickType.Quote) { Consolidated = new List(); Consolidator = new TickQuoteBarConsolidator(resolution.ToTimeSpan()); Consolidator.DataConsolidated += (sender, consolidated) => { Consolidated.Add(consolidated as QuoteBar); }; } } /// /// Use to consolidate trade ticks into a specified resolution /// public class TradeTickAggregator : TickAggregator { public TradeTickAggregator(Resolution resolution) : base(resolution, TickType.Trade) { Consolidated = new List(); Consolidator = new TickConsolidator(resolution.ToTimeSpan()); Consolidator.DataConsolidated += (sender, consolidated) => { Consolidated.Add(consolidated as TradeBar); }; } } /// /// Use to consolidate open interest ticks into a specified resolution /// public class OpenInterestTickAggregator : TickAggregator { public OpenInterestTickAggregator(Resolution resolution) : base(resolution, TickType.OpenInterest) { Consolidated = new List(); Consolidator = new OpenInterestConsolidator(resolution.ToTimeSpan()); Consolidator.DataConsolidated += (sender, consolidated) => { Consolidated.Add(consolidated as OpenInterest); }; } } /// /// Use to yield ticks unmodified into the consolidated data collection /// public class IdentityTickAggregator : TickAggregator { public IdentityTickAggregator(TickType tickType) : base(Resolution.Tick, tickType) { Consolidated = new List(); Consolidator = FilteredIdentityDataConsolidator.ForTickType(tickType); Consolidator.DataConsolidated += (sender, consolidated) => { Consolidated.Add(consolidated as Tick); }; } } }