/// <summary> /// Data delivery has received a dataDelivery update. /// </summary> void _dataDelivery_DataHistoryUpdateDelegate(ISourceDataDelivery dataDelivery, DataSessionInfo session, DataHistoryUpdate update) { if (_sessionInfo.Equals(session) == false) { return; } if (update.Period != _period.Value) {// This update is aimed at another provider. return; } DataBarUpdateType?updateType = null; if (_dataBars.Count == 0) { updateType = DataBarUpdateType.Initial; } _barFilter.FilterUpdate(dataDelivery, session, update); int updatedBarsCount = 0; lock (this) { _lastDataUpdate = DateTime.Now; // Add new bars - search for new later bars. for (int i = 0; i < update.DataBarsUnsafe.Count; i++) { if (_dataBars.Count == 0 || update.DataBarsUnsafe[i].DateTime > _dataBars[_dataBars.Count - 1].DateTime) { if (updateType.HasValue == false) { updateType = DataBarUpdateType.HistoryUpdate; } updatedBarsCount++; _dataBars.Add(update.DataBarsUnsafe[i]); _cachedDataBarIndexSearches.Add(update.DataBarsUnsafe[i].DateTime, _dataBars.Count - 1); } } bool preTimeUpdate = false; // Add new bars - search for previous bars - a separate cycle needed since we need to move backwards on this. for (int i = update.DataBarsUnsafe.Count - 1; i >= 0; i--) { if (_dataBars.Count > 0 && update.DataBarsUnsafe[i].DateTime < _dataBars[0].DateTime) {// This is a bar from previous history, we do not know about - insert first place. _dataBars.Insert(0, update.DataBarsUnsafe[i]); preTimeUpdate = true; } } // Also check the last 5 units for any requotes that might have been sent, // this happens when price changes and we get updates for the last unit. for (int i = 0; i < 5 && update.DataBarsUnsafe.Count - 1 - i > 0 && _dataBars.Count - 1 - i > 0; i++) { if (update.DataBarsUnsafe[update.DataBarsUnsafe.Count - 1 - i].DateTime == _dataBars[_dataBars.Count - 1 - i].DateTime /*&& update.DataBarsUnsafe[update.DataBarsUnsafe.Count - 1 - i].Equals(_dataBars[_dataBars.Count - 1 - i]) == false*/) { updatedBarsCount++; // Since this update is only when the date times are the same, the helper cache dictionary needs not be updated. _dataBars[_dataBars.Count - 1 - i] = update.DataBarsUnsafe[update.DataBarsUnsafe.Count - 1 - i]; if (updateType.HasValue == false) { updateType = DataBarUpdateType.HistoryUpdate; } } } if (preTimeUpdate) {// Make a full update if we have inserted something in the beggining. updateType = DataBarUpdateType.HistoryUpdate; updatedBarsCount = _dataBars.Count; } } if (updateType.HasValue && DataBarHistoryUpdateEvent != null) { DataBarHistoryUpdateEvent(this, updateType.Value, updatedBarsCount); } }