/// <summary> /// /// </summary> public bool AcceptsUpdate(DataHistoryUpdate responce) { if (responce.BarDataAssigned && _dataBarSubscriptions.Contains(responce.Period)) { return(true); } if (responce.TickDataAssigned && _tickSubscription) { return(true); } return(false); }
/// <summary> /// /// </summary> public void FilterUpdate(ISourceDataDelivery dataDelivery, DataSessionInfo session, DataHistoryUpdate update) { if (_enabled == false) { return; } decimal?lastHigh = null; decimal?lastLow = null; decimal divergence = MaxDivergenceCoefficientStock; if (session.Symbol.IsForexPair) { divergence = MaxDivergenceCoefficientForex; } int consecutiveSpikes = 0; for (int i = 0; i < update.DataBarsUnsafe.Count; i++) { if (lastHigh.HasValue && lastLow.HasValue) { DataBar bar = update.DataBarsUnsafe[i]; if ((bar.High > lastHigh.Value * (1 + divergence) || bar.Low < lastLow.Value / (1 + divergence)) && consecutiveSpikes <= _maximumConsecutiveSpikes) {// Bar spike detected. consecutiveSpikes++; SystemMonitor.Report("Spike detected in data [" + session.Symbol.Name + "]. Bar values limited to previous [" + lastHigh.Value + ", " + bar.High + "; " + lastLow.Value + ", " + bar.Low + "]."); update.DataBarsUnsafe[i] = new DataBar(bar.DateTime, GeneralHelper.LimitRange(bar.Open, lastLow.Value, lastHigh.Value), GeneralHelper.LimitRange(bar.High, lastLow.Value, lastHigh.Value), GeneralHelper.LimitRange(bar.Low, lastLow.Value, lastHigh.Value), GeneralHelper.LimitRange(bar.Close, lastLow.Value, lastHigh.Value), bar.Volume); } else { consecutiveSpikes = 0; } } lastHigh = update.DataBarsUnsafe[i].High; lastLow = update.DataBarsUnsafe[i].Low; } }
/// <summary> /// /// </summary> public DataHistoryUpdateMessage(DataSessionInfo session, DataHistoryUpdate update, bool operationResult) : base(session, operationResult) { _update = update; }
void _dataDelivery_DataHistoryUpdateEvent(ISourceDataDelivery dataDelivery, DataSessionInfo session, DataHistoryUpdate update) { if (update.BarDataAssigned) { lock (this) { _lastDataBar = update.DataBarsUnsafe[update.DataBarsUnsafe.Count - 1]; } } }
/// <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); } }
public void UpdateDataHistory(DataSessionInfo session, DataHistoryUpdate update) { if (OperationalState != OperationalStateEnum.Operational) { SystemMonitor.Warning("Stub used while not operational, operation ignored."); return; } DataHistoryUpdateMessage message = new DataHistoryUpdateMessage(session, update, true); CombinedDataSubscriptionInformation combined; lock(this) { combined = GetUnsafeSessionSubscriptions(session); } lock(combined) { foreach (KeyValuePair<TransportInfo, DataSubscriptionInfo> info in combined.SubscriptionsUnsafe.Values) { if (info.Value.AcceptsUpdate(update)) { SendResponding(info.Key, message); } } } }
/// <summary> /// /// </summary> public bool AcceptsUpdate(DataHistoryUpdate response) { if (response.BarDataAssigned && _dataBarSubscriptions.Contains(response.Period)) { return true; } if (response.TickDataAssigned && _tickSubscription) { return true; } return false; }
/// <summary> /// OperationId is not mandatory - but is should be there when the update was requested by a special recepient. /// </summary> public void TradingValuesUpdate(string symbol, int operationId, double time, int period, int availableBarsCount, Int64[] times, decimal[] opens, decimal[] closes, decimal[] highs, decimal[] lows, decimal[] volumes) { TracerHelper.TraceEntry(); CombinedDataSubscriptionInformation session = GetDataSession(symbol); if (session == null) { SystemMonitor.Error("Failed to find symbol session [" + symbol + "], quotes not sent."); return; } try { // History update. TimeSpan periodValue = TimeSpan.FromMinutes(period); DataHistoryUpdate update = new DataHistoryUpdate(periodValue, GenerateDataBars(periodValue, times, opens, closes, highs, lows, volumes)); update.AvailableHistorySize = availableBarsCount; DataHistoryUpdateMessage message = new DataHistoryUpdateMessage(session.SessionInformation.Info, update, true); SendToDataSubscribers(session, null, message); } catch (Exception ex) {// Make sure we handle any possible unexpected exceptions, as otherwise they bring the // entire package (MT4 included) down with a bad error. SystemMonitor.Error(ex.Message); } TracerHelper.TraceExit(); }
/// <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); } }
void _dataDelivery_DataHistoryUpdateDelegate(ISourceDataDelivery dataDelivery, DataSessionInfo session, DataHistoryUpdate update) { if (session.Equals(_session) == false || update.DataTicksUnsafe.Count == 0) { return; } DataTickUpdateType?updateType = null; if (_dataTicks.Count == 0) { updateType = DataTickUpdateType.HistoryUpdate; } lock (this) { _lastDataUpdate = DateTime.Now; for (int i = 0; i < update.DataTicksUnsafe.Count; i++) { if (_dataTicks.Count == 0 || update.DataTicksUnsafe[i].DateTime > _dataTicks[_dataTicks.Count - 1].DateTime) { if (updateType.HasValue == false) { updateType = DataTickUpdateType.HistoryUpdate; } _dataTicks.Add(update.DataTicksUnsafe[i]); _cachedDataTickIndexSearches.Add(update.DataTicksUnsafe[i].DateTime, i); } } // 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.DataTicksUnsafe.Count - 1 - i > 0 && _dataTicks.Count - 1 - i > 0; i++) { if (update.DataTicksUnsafe[update.DataTicksUnsafe.Count - 1 - i].DateTime == _dataTicks[_dataTicks.Count - 1 - i].DateTime && update.DataTicksUnsafe[update.DataTicksUnsafe.Count - 1 - i].Equals(_dataTicks[_dataTicks.Count - 1 - i]) == false) { // Since this update is only when the date times are the same, the helper cache dictionary needs not be updated. _dataTicks[_dataTicks.Count - 1 - i] = update.DataTicksUnsafe[update.DataTicksUnsafe.Count - 1 - i]; if (updateType.HasValue == false) { updateType = DataTickUpdateType.HistoryUpdate; } } } } if (updateType.HasValue && DataTickHistoryUpdateEvent != null) { DataTickHistoryUpdateEvent(this, updateType.Value); } }
void _dataDelivery_DataHistoryUpdateDelegate(ISourceDataDelivery dataDelivery, DataSessionInfo session, DataHistoryUpdate update) { if (session.Equals(_session) == false || update.DataTicksUnsafe.Count == 0) { return; } DataTickUpdateType? updateType = null; if (_dataTicks.Count == 0) { updateType = DataTickUpdateType.HistoryUpdate; } lock (this) { _lastDataUpdate = DateTime.Now; for (int i = 0; i < update.DataTicksUnsafe.Count; i++) { if (_dataTicks.Count == 0 || update.DataTicksUnsafe[i].DateTime > _dataTicks[_dataTicks.Count - 1].DateTime) { if (updateType.HasValue == false) { updateType = DataTickUpdateType.HistoryUpdate; } _dataTicks.Add(update.DataTicksUnsafe[i]); _cachedDataTickIndexSearches.Add(update.DataTicksUnsafe[i].DateTime, i); } } // 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.DataTicksUnsafe.Count - 1 - i > 0 && _dataTicks.Count - 1 - i > 0; i++) { if (update.DataTicksUnsafe[update.DataTicksUnsafe.Count - 1 - i].DateTime == _dataTicks[_dataTicks.Count - 1 - i].DateTime && update.DataTicksUnsafe[update.DataTicksUnsafe.Count - 1 - i].Equals(_dataTicks[_dataTicks.Count - 1 - i]) == false) { // Since this update is only when the date times are the same, the helper cache dictionary needs not be updated. _dataTicks[_dataTicks.Count - 1 - i] = update.DataTicksUnsafe[update.DataTicksUnsafe.Count - 1 - i]; if (updateType.HasValue == false) { updateType = DataTickUpdateType.HistoryUpdate; } } } } if (updateType.HasValue && DataTickHistoryUpdateEvent != null) { DataTickHistoryUpdateEvent(this, updateType.Value); } }
/// <summary> /// /// </summary> public void FilterUpdate(ISourceDataDelivery dataDelivery, DataSessionInfo session, DataHistoryUpdate update) { if (_enabled == false) { return; } decimal? lastHigh = null; decimal? lastLow = null; decimal divergence = MaxDivergenceCoefficientStock; if (session.Symbol.IsForexPair) { divergence = MaxDivergenceCoefficientForex; } int consecutiveSpikes = 0; for (int i = 0; i < update.DataBarsUnsafe.Count; i++) { if (lastHigh.HasValue && lastLow.HasValue) { DataBar bar = update.DataBarsUnsafe[i]; if ( (bar.High > lastHigh.Value * (1 + divergence) || bar.Low < lastLow.Value / (1 + divergence)) && consecutiveSpikes <= _maximumConsecutiveSpikes) {// Bar spike detected. consecutiveSpikes++; SystemMonitor.Report("Spike detected in data [" + session.Symbol.Name + "]. Bar values limited to previous [" + lastHigh.Value + ", " + bar.High + "; " + lastLow.Value + ", " + bar.Low + "]."); update.DataBarsUnsafe[i] = new DataBar(bar.DateTime, GeneralHelper.LimitRange(bar.Open, lastLow.Value, lastHigh.Value), GeneralHelper.LimitRange(bar.High, lastLow.Value, lastHigh.Value), GeneralHelper.LimitRange(bar.Low, lastLow.Value, lastHigh.Value), GeneralHelper.LimitRange(bar.Close, lastLow.Value, lastHigh.Value), bar.Volume); } else { consecutiveSpikes = 0; } } lastHigh = update.DataBarsUnsafe[i].High; lastLow = update.DataBarsUnsafe[i].Low; } }
/// <summary> /// Request bar dataDelivery from entry. /// </summary> public bool RequestDataHistoryUpdate(DataSessionInfo sessionInfo, DataHistoryRequest request, bool waitResult) { DataStoreEntry entry = DataStore.Instance.GetEntryBySessionInfo(sessionInfo); if (this.OperationalState != OperationalStateEnum.Operational || entry == null) { SystemMonitor.OperationError("Data history request received while not operational, or invalid session requrested."); return false; } if (entry.Period != request.Period) { SystemMonitor.OperationError("Data history request received but period not recognized."); return false; } if (request.MaxValuesRetrieved.HasValue == false) { request.MaxValuesRetrieved = int.MaxValue; } if (request.StartIndex.HasValue == false) { request.StartIndex = -1; } GeneralHelper.GenericReturnDelegate<bool> operationDelegate = delegate() { if (request.IsTickBased) { DataReaderWriter<DataTick> readerWriter = entry.GetDataTickReaderWriter(); List<DataTick> dataTicks; DataHistoryUpdate update = new DataHistoryUpdate(request.Period, new DataTick[] { }); if (readerWriter.Read(request.StartIndex.Value, request.MaxValuesRetrieved.Value, out dataTicks)) { update.DataTicksUnsafe.AddRange(dataTicks); if (DataHistoryUpdateEvent != null) { DataHistoryUpdateEvent(this, sessionInfo, update); } return true; } } else { DataReaderWriter<DataBar> readerWriter = entry.GetDataBarReaderWriter(); if (readerWriter == null) { SystemMonitor.OperationError("Failed to establish file reader writer for entry."); return false; } List<DataBar> dataBars; DataHistoryUpdate update = new DataHistoryUpdate(request.Period, new DataBar[] { }); bool readResult = false; if (request.StartIndex.Value < 0) {// Instruction is to read the last count items. readResult = readerWriter.ReadLast( request.MaxValuesRetrieved.Value, out dataBars); } else { readResult = readerWriter.Read(request.StartIndex.Value, request.MaxValuesRetrieved.Value, out dataBars); } if (readResult) { update.DataBarsUnsafe.AddRange(dataBars); if (DataHistoryUpdateEvent != null) { DataHistoryUpdateEvent(this, sessionInfo, update); } return true; } } return false; }; if (waitResult) { return operationDelegate(); } else { GeneralHelper.FireAndForget(operationDelegate); return true; } }