/// <summary>
        ///
        /// </summary>
        public bool AcceptsUpdate(DataHistoryUpdate responce)
        {
            if (responce.BarDataAssigned && _dataBarSubscriptions.Contains(responce.Period))
            {
                return(true);
            }

            if (responce.TickDataAssigned && _tickSubscription)
            {
                return(true);
            }

            return(false);
        }
示例#2
0
        /// <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;
 }
示例#4
0
 void _dataDelivery_DataHistoryUpdateEvent(ISourceDataDelivery dataDelivery, DataSessionInfo session, DataHistoryUpdate update)
 {
     if (update.BarDataAssigned)
     {
         lock (this)
         {
             _lastDataBar = update.DataBarsUnsafe[update.DataBarsUnsafe.Count - 1];
         }
     }
 }
示例#5
0
        /// <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_DataHistoryUpdateEvent(ISourceDataDelivery dataDelivery, DataSessionInfo session, DataHistoryUpdate update)
 {
     if (update.BarDataAssigned)
     {
         lock (this)
         {
             _lastDataBar = update.DataBarsUnsafe[update.DataBarsUnsafe.Count - 1];
         }
     }
 }
        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);
            }
        }
示例#11
0
        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;
            }
        }