private void AppendTick(Security security, ExecutionMessage tick)
        {
            var time  = tick.ServerTime;
            var price = tick.TradePrice.Value;

            if (_candle == null || time >= _candle.CloseTime)
            {
                if (_candle != null)
                {
                    _candle.State = CandleStates.Finished;

                    lock (_updatedCandles.SyncRoot)
                        _updatedCandles[_candle.OpenTime] = _candle;

                    _lastPrice = _candle.ClosePrice;
                    _tradeGenerator.Process(tick);
                }

                //var t = TimeframeSegmentDataSeries.GetTimeframePeriod(time.DateTime, _timeframe);
                var bounds = _timeframe.GetCandleBounds(time, security.Board);

                _candle = new TimeFrameCandle
                {
                    TimeFrame = _timeframe,
                    OpenTime  = bounds.Min,
                    CloseTime = bounds.Max,
                    Security  = security,
                };

                _volumeProfile      = new CandleMessageVolumeProfile();
                _candle.PriceLevels = _volumeProfile.PriceLevels;

                _candle.OpenPrice = _candle.HighPrice = _candle.LowPrice = _candle.ClosePrice = price;
            }

            if (time < _candle.OpenTime)
            {
                throw new InvalidOperationException("invalid time");
            }

            if (price > _candle.HighPrice)
            {
                _candle.HighPrice = price;
            }

            if (price < _candle.LowPrice)
            {
                _candle.LowPrice = price;
            }

            _candle.ClosePrice = price;

            _candle.TotalVolume += tick.TradeVolume.Value;

            _volumeProfile.Update(new TickCandleBuilderSourceValue(tick));

            lock (_updatedCandles.SyncRoot)
                _updatedCandles[_candle.OpenTime] = _candle;
        }
        /// <summary>
        /// The total number of asks in the <see cref="CandleMessageVolumeProfile"/>.
        /// </summary>
        /// <param name="volumeProfile">Volume profile.</param>
        /// <returns>The total number of asks.</returns>
        public static decimal TotalSellCount(this CandleMessageVolumeProfile volumeProfile)
        {
            if (volumeProfile == null)
            {
                throw new ArgumentNullException(nameof(volumeProfile));
            }

            return(volumeProfile.PriceLevels.Select(p => p.SellCount).Sum());
        }
Exemple #3
0
        private void AppendTick(Security security, ExecutionMessage tick)
        {
            var time  = tick.ServerTime;
            var price = tick.TradePrice.Value;

            if (_candle == null || time >= _candle.CloseTime)
            {
                if (_candle != null)
                {
                    lock (_updatedCandles.SyncRoot)
                        _updatedCandles[_candle.OpenTime] = Tuple.Create(_candle, true);

                    _lastPrice = _candle.ClosePrice;
                    _tradeGenerator.Process(tick);
                }

                var bounds = _timeframe.GetCandleBounds(time, security.Board);

                _candle = new TimeFrameCandle
                {
                    TimeFrame = _timeframe,
                    OpenTime  = bounds.Min,
                    CloseTime = bounds.Max,
                    Security  = security,
                };

                _volumeProfile      = new CandleMessageVolumeProfile();
                _candle.PriceLevels = _volumeProfile.PriceLevels;

                _candle.OpenPrice = _candle.HighPrice = _candle.LowPrice = _candle.ClosePrice = price;
            }

            if (time < _candle.OpenTime)
            {
                throw new InvalidOperationException("invalid time");
            }

            if (price > _candle.HighPrice)
            {
                _candle.HighPrice = price;
            }

            if (price < _candle.LowPrice)
            {
                _candle.LowPrice = price;
            }

            _candle.ClosePrice = price;

            _candle.TotalVolume += tick.TradeVolume.Value;

            lock (_volumeProfile.PriceLevels)
                _volumeProfile.Update(tick.TradePrice.Value, tick.TradeVolume, tick.OriginSide);

            lock (_updatedCandles.SyncRoot)
                _updatedCandles[_candle.OpenTime] = Tuple.Create(_candle, false);
        }
        /// <summary>
        /// POC (Point Of Control) returns <see cref="CandlePriceLevel"/> which had the maximum volume.
        /// </summary>
        /// <param name="volumeProfile">Volume profile.</param>
        /// <returns>The <see cref="CandlePriceLevel"/> which had the maximum volume.</returns>
        public static CandlePriceLevel PoC(this CandleMessageVolumeProfile volumeProfile)
        {
            if (volumeProfile == null)
            {
                throw new ArgumentNullException(nameof(volumeProfile));
            }

            var max = volumeProfile.PriceLevels.Select(p => p.BuyVolume + p.SellVolume).Max();

            return(volumeProfile.PriceLevels.FirstOrDefault(p => p.BuyVolume + p.SellVolume == max));
        }
        /// <summary>
        /// It returns the price level at which the minimum <see cref="Delta"/> is passed.
        /// </summary>
        /// <param name="volumeProfile">Volume profile.</param>
        /// <returns>The price level.</returns>
        public static CandlePriceLevel PriceLevelOfMinDelta(this CandleMessageVolumeProfile volumeProfile)
        {
            if (volumeProfile == null)
            {
                throw new ArgumentNullException(nameof(volumeProfile));
            }

            var delta = volumeProfile.PriceLevels.Select(p => p.BuyVolume - p.SellVolume).Min();

            return(volumeProfile.PriceLevels.FirstOrDefault(p => p.BuyVolume - p.SellVolume == delta));
        }
        /// <summary>
        /// To update the profile with new value.
        /// </summary>
        /// <param name="volumeProfile">Volume profile.</param>
        /// <param name="transform">The data source transformation.</param>
        public static void Update(this CandleMessageVolumeProfile volumeProfile, ICandleBuilderValueTransform transform)
        {
            if (volumeProfile == null)
            {
                throw new ArgumentNullException(nameof(volumeProfile));
            }

            if (transform == null)
            {
                throw new ArgumentNullException(nameof(transform));
            }

            volumeProfile.Update(transform.Price, transform.Volume, transform.Side);
        }
Exemple #7
0
        /// <summary>
        /// To update the profile with new value.
        /// </summary>
        /// <param name="volumeProfile">Volume profile.</param>
        /// <param name="value">Value.</param>
        public static void Update(this CandleMessageVolumeProfile volumeProfile, ICandleBuilderSourceValue value)
        {
            if (volumeProfile == null)
            {
                throw new ArgumentNullException(nameof(volumeProfile));
            }

            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            volumeProfile.Update(value.Price, value.Volume, value.OrderDirection);
        }
Exemple #8
0
        /// <summary>
        /// To calculate the area for the candles group.
        /// </summary>
        /// <param name="candles">Candles.</param>
        /// <returns>The area.</returns>
        public static CandleMessageVolumeProfile GetValueArea(this IEnumerable <Candle> candles)
        {
            var area = new CandleMessageVolumeProfile();

            foreach (var candle in candles)
            {
                if (candle.PriceLevels == null)
                {
                    continue;
                }

                foreach (var priceLevel in candle.PriceLevels)
                {
                    area.Update(priceLevel);
                }
            }

            area.Calculate();
            return(area);
        }
 /// <summary>
 /// The total Delta which was below <see cref="PoC"/>.
 /// </summary>
 /// <param name="volumeProfile">Volume profile.</param>
 /// <returns>Delta.</returns>
 public static decimal DeltaBelowPoC(this CandleMessageVolumeProfile volumeProfile)
 {
     return(volumeProfile.BuyVolBelowPoC() - volumeProfile.SellVolBelowPoC());
 }
 /// <summary>
 /// The difference between <see cref="TotalBuyVolume"/> and <see cref="TotalSellVolume"/>.
 /// </summary>
 /// <param name="volumeProfile">Volume profile.</param>
 /// <returns>Delta.</returns>
 public static decimal Delta(this CandleMessageVolumeProfile volumeProfile)
 {
     return(volumeProfile.TotalBuyVolume() - volumeProfile.TotalSellVolume());
 }
 /// <summary>
 /// The total volume which was above <see cref="PoC"/>.
 /// </summary>
 /// <param name="volumeProfile">Volume profile.</param>
 /// <returns>Total volume.</returns>
 public static decimal VolumeAbovePoC(this CandleMessageVolumeProfile volumeProfile)
 {
     return(volumeProfile.BuyVolAbovePoC() + volumeProfile.SellVolAbovePoC());
 }
        /// <summary>
        /// The total volume of asks which was below <see cref="PoC"/>.
        /// </summary>
        /// <param name="volumeProfile">Volume profile.</param>
        /// <returns>The total volume of asks.</returns>
        public static decimal SellVolBelowPoC(this CandleMessageVolumeProfile volumeProfile)
        {
            var poc = volumeProfile.PoC();

            return(volumeProfile.PriceLevels.Where(p => p.Price < poc.Price).Select(p => p.SellVolume).Sum());
        }
        /// <summary>
        /// The total volume of bids which was above <see cref="PoC"/>.
        /// </summary>
        /// <param name="volumeProfile">Volume profile.</param>
        /// <returns>The total volume of bids.</returns>
        public static decimal BuyVolAbovePoC(this CandleMessageVolumeProfile volumeProfile)
        {
            var poc = volumeProfile.PoC();

            return(volumeProfile.PriceLevels.Where(p => p.Price > poc.Price).Select(p => p.BuyVolume).Sum());
        }