public void GivenVolumesToAggregateWhenAggregatedThenCorrectVolumesAreReturned() { var powerTrades = CreateTrades(); var tradeAggregator = new TradeAggregator(); var aggregateTrades = tradeAggregator.AggregateTrades(powerTrades).ToList(); for (var i = 0; i < 24; i++) { Assert.AreEqual(i < 11 ? 150 : 80, aggregateTrades[i].Volume); } }
public void Aggregate_should_return(IEnumerable <Trade> trades, IEnumerable <CsvModel> expected) { ITradeAggregator tradeAggregator = new TradeAggregator(); CollectionAssert.AreEqual(expected, tradeAggregator.Aggregate(trades)); }
/// <summary> /// Adds a datasubscription which is derived from the requested data aggregator instance /// Force tick will force the data to contain the highest granularity (otherwise it might be based on 1-minute data) /// TODO: add unit test, if we request 1 minute data and than request tick data we should keep the tick data request and replace all 1 minute request with the tick data request? (so that we only keep the tick data request) /// TODO: we will only do ticks or tradebars! (where a trade bar is based on any data) /// </summary> /// <param name="quantfund"></param> /// <param name="security">The security.</param> /// <param name="aggregator">The aggregator.</param> /// <param name="forcetick">if set to <c>true</c> [forcetick].</param> /// <returns>Can be a different dataggregator due to change in data requested</returns> public DataAggregator AddSubscription(IQuantFund quantfund, Security security, DataAggregator aggregator, bool forcetick = false) { //Initial values TimeSpan?aggregationneeded = null; DataType datatypeneeded = DataType.Tick; TimeSpan preaggregated = TimeSpan.FromMinutes(1); if (!forcetick) { //TradeBar -> TradeBar if (aggregator is TimeSerieAggregator <TradeBar, TradeBar> tradetotrade && tradetotrade.IsTimeBased) { if (tradetotrade.Period.Value.TotalSeconds % 60 == 0D) { aggregator = new TradeAggregator(tradetotrade.Period.Value); aggregationneeded = preaggregated; datatypeneeded = DataType.TradeBar; } } //Tick -> TradeBar if (aggregator is TimeSerieAggregator <Tick, TradeBar> ticktobar && ticktobar.IsTimeBased) { if (ticktobar.Period.Value.TotalSeconds % 60 == 0D) { aggregator = new TickQuoteBarAggregator(ticktobar.Period.Value); aggregationneeded = TimeSpan.FromMinutes(1); datatypeneeded = DataType.TradeBar; } } } //get and add subscription var subscription = DataSubscriptionRequest.CreateSubscriptionRequest(security.Ticker, _datafeed.DataSource, aggregationneeded, datatypeneeded); subscription = AddSubscription(subscription); //Add base currency conversion AddBaseCurrencyConversionFeed(security); //Check if we already have a similar data aggregator, reuse the existing version if possible if (_registeredsubscriptions.ContainsKey(quantfund.FundId)) { var found = _registeredsubscriptions[quantfund.FundId].FirstOrDefault(x => x.Request.GetSubscriptionName() == subscription.GetSubscriptionName()); var existing = found?.Aggregators.FirstOrDefault(x => x.Name == aggregator.Name); if (existing != null) { return(existing); } else if (found == null) { _registeredsubscriptions[quantfund.FundId].Add(new DataSubscription(quantfund.FundId, subscription, security, security.Exchange.TimeZone, aggregator)); } else { found.Aggregators.Add(aggregator); } } else { //Add new _registeredsubscriptions.Add(quantfund.FundId, new List <DataSubscription>()); _registeredsubscriptions[quantfund.FundId].Add(new DataSubscription(quantfund.FundId, subscription, security, security.Exchange.TimeZone, aggregator)); } //Return our current aggregator return(aggregator); }
public void Merge( TradeAggregator Group ) { values.AddRange( Group.values ); }