/// <summary> /// Pushes the tick into this enumerator. This tick will be aggregated into a quote bar /// and emitted after the alotted time has passed /// </summary> /// <param name="data">The new data to be aggregated</param> public void ProcessData(BaseData data) { QuoteBar working; var tick = data as Tick; var qty = tick == null ? 0 : tick.Quantity; var bidPrice = tick == null ? data.Value : tick.BidPrice; var askPrice = tick == null ? data.Value : tick.AskPrice; var bidSize = tick == null ? 0m : tick.BidSize; var askSize = tick == null ? 0m : tick.AskSize; if (!_queue.TryPeek(out working)) { // the consumer took the working bar, or time ticked over into next bar var utcNow = _timeProvider.GetUtcNow(); var currentLocalTime = utcNow.ConvertFromUtc(_timeZone); var barStartTime = currentLocalTime.RoundDown(_barSize); working = new QuoteBar(); working.Update(data.Value, bidPrice, askPrice, qty, bidSize, askSize); working.Period = _barSize; working.Time = barStartTime; working.Symbol = data.Symbol; _queue.Enqueue(working); if (_liveMode) { _realTimeScheduleEventService.ScheduleEvent(_barSize.Subtract(currentLocalTime - barStartTime), utcNow); } } else { // we're still within this bar size's time working.Update(data.Value, bidPrice, askPrice, qty, bidSize, askSize); } }
/// <summary> /// Pushes the tick into this enumerator. This tick will be aggregated into a quote bar /// and emitted after the alotted time has passed /// </summary> /// <param name="data">The new data to be aggregated</param> public void ProcessData(BaseData data) { QuoteBar working; var tick = data as Tick; var qty = tick == null ? 0 : tick.Quantity; var bidPrice = tick == null ? data.Value : tick.BidPrice; var askPrice = tick == null ? data.Value : tick.AskPrice; var bidSize = tick == null ? 0m : tick.BidSize; var askSize = tick == null ? 0m : tick.AskSize; if (!_queue.TryPeek(out working)) { // the consumer took the working bar, or time ticked over into next bar var utcNow = _timeProvider.GetUtcNow(); var currentLocalTime = utcNow.ConvertFromUtc(_timeZone); var barStartTime = currentLocalTime.RoundDown(_barSize); working = new QuoteBar(); // open ask and bid should match previous close ask and bid if (Current != null) { // note that we will only fill forward previous close ask and bid when a new data point comes in and we generate a new working bar which is not a fill forward bar var previous = Current as QuoteBar; working.Update(0, previous.Bid?.Close ?? 0, previous.Ask?.Close ?? 0, 0, previous.LastBidSize, previous.LastAskSize); } working.Update(data.Value, bidPrice, askPrice, qty, bidSize, askSize); working.Period = _barSize; working.Time = barStartTime; working.Symbol = data.Symbol; _queue.Enqueue(working); if (_liveMode) { _realTimeScheduleEventService.ScheduleEvent(_barSize.Subtract(currentLocalTime - barStartTime), utcNow); } } else { // we're still within this bar size's time working.Update(data.Value, bidPrice, askPrice, qty, bidSize, askSize); } }
public void QuoteBar_CanCreateCorrectBars() { var nbar = new QuoteBar(); nbar.Update(10, 10, 10, 10, 10, 10); nbar.Open.Should().Be(10); nbar.High.Should().Be(10); nbar.Low.Should().Be(10); nbar.Close.Should().Be(10); nbar = new QuoteBar(); nbar.Ask = new BarImpl(11, 11, 11, 11); nbar.Open.Should().Be(11); nbar.High.Should().Be(11); nbar.Low.Should().Be(11); nbar.Close.Should().Be(11); nbar.Update(12, 12, 12, 1, 1, 1); nbar.Open.Should().Be(11); nbar.High.Should().Be(12); nbar.Low.Should().Be(11); nbar.Close.Should().Be(12); }