コード例 #1
0
ファイル: VolumeProfile.cs プロジェクト: pantov/StockSharp
		/// <summary>
		/// To update the profile with new value.
		/// </summary>
		/// <param name="value">Value.</param>
		public void Update(ICandleBuilderSourceValue value)
		{
			if (value.OrderDirection == null)
				return;

			_volumeProfileInfo.SafeAdd(value.Price, key => new PriceLevel(key)).Update(value);
		}
コード例 #2
0
ファイル: PriceLevel.cs プロジェクト: hbwjz/StockSharp
		/// <summary>
		/// To update the price level with the new value.
		/// </summary>
		/// <param name="value">Value.</param>
		public void Update(ICandleBuilderSourceValue value)
		{
			var side = value.OrderDirection;

			if (side == null)
				throw new ArgumentOutOfRangeException();

			if (side == Sides.Buy)
			{
				BuyVolume += value.Volume;
				BuyCount++;
				BuyVolumes.Add(value.Volume);
			}
			else
			{
				SellVolume += value.Volume;
				SellCount++;
				SellVolumes.Add(value.Volume);
			}
		}
コード例 #3
0
 /// <summary>
 /// Whether the candle is created before data adding.
 /// </summary>
 /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
 /// <param name="candle">Candle.</param>
 /// <param name="value">Data by which it is decided to end the current candle creation.</param>
 /// <returns><see langword="true" /> if the candle should be finished. Otherwise, <see langword="false" />.</returns>
 protected override bool IsCandleFinishedBeforeChange(MarketDataMessage message, RangeCandleMessage candle, ICandleBuilderSourceValue value)
 {
     return((decimal)(candle.LowPrice + candle.PriceRange) <= candle.HighPrice);
 }
コード例 #4
0
 /// <summary>
 /// Whether the candle is created before data adding.
 /// </summary>
 /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
 /// <param name="candle">Candle.</param>
 /// <param name="value">Data by which it is decided to end the current candle creation.</param>
 /// <returns><see langword="true" /> if the candle should be finished. Otherwise, <see langword="false" />.</returns>
 protected override bool IsCandleFinishedBeforeChange(MarketDataMessage message, VolumeCandleMessage candle, ICandleBuilderSourceValue value)
 {
     return(candle.TotalVolume >= candle.Volume);
 }
コード例 #5
0
        /// <summary>
        /// To update the candle data.
        /// </summary>
        /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
        /// <param name="candle">Candle.</param>
        /// <param name="value">Data.</param>
        protected override void UpdateCandle(MarketDataMessage message, TickCandleMessage candle, ICandleBuilderSourceValue value)
        {
            base.UpdateCandle(message, candle, value);

            var ticks = candle.TotalTicks;

            if (ticks == null)
            {
                throw new InvalidOperationException();
            }

            candle.TotalTicks = ticks.Value + 1;
        }
コード例 #6
0
 /// <summary>
 /// To create a new candle.
 /// </summary>
 /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
 /// <param name="currentCandle">The current candle.</param>
 /// <param name="value">Data with which a new candle should be created.</param>
 /// <returns>Created candle.</returns>
 protected override TickCandleMessage CreateCandle(MarketDataMessage message, TickCandleMessage currentCandle, ICandleBuilderSourceValue value)
 {
     return(FirstInitCandle(message, new TickCandleMessage
     {
         MaxTradeCount = (int)message.Arg,
         OpenTime = value.Time,
         CloseTime = value.Time,
         HighTime = value.Time,
         LowTime = value.Time,
         TotalTicks = 1,
     }, value));
 }
コード例 #7
0
        ///// <summary>
        ///// Reset state.
        ///// </summary>
        //public override void Reset()
        //{
        //	base.Reset();

        //	_timeoutInfos.Clear();
        //}

        /// <summary>
        /// To create a new candle.
        /// </summary>
        /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
        /// <param name="currentCandle">The current candle.</param>
        /// <param name="value">Data with which a new candle should be created.</param>
        /// <returns>Created candle.</returns>
        protected override TimeFrameCandleMessage CreateCandle(MarketDataMessage message, TimeFrameCandleMessage currentCandle, ICandleBuilderSourceValue value)
        {
            var timeFrame = (TimeSpan)message.Arg;

            var board  = _exchangeInfoProvider.GetOrCreateBoard(message.SecurityId.BoardCode);
            var bounds = timeFrame.GetCandleBounds(value.Time, board, board.WorkingTime);

            if (value.Time < bounds.Min)
            {
                return(null);
            }

            var openTime = bounds.Min;

            var candle = FirstInitCandle(message, new TimeFrameCandleMessage
            {
                TimeFrame = timeFrame,
                OpenTime  = openTime,
                HighTime  = openTime,
                LowTime   = openTime,
                CloseTime = openTime,                 // реальное окончание свечи определяет по последней сделке
            }, value);

            return(candle);
        }
コード例 #8
0
        /// <summary>
        /// Сформирована ли свеча до добавления данных.
        /// </summary>
        /// <param name="series">Серия свечек.</param>
        /// <param name="candle">Свеча.</param>
        /// <param name="value">Данные, с помощью которых принимается решение о необходимости окончания формирования текущей свечи.</param>
        /// <returns><see langword="true"/>, если свечу необходимо закончить. Иначе, <see langword="false"/>.</returns>
        protected override bool IsCandleFinishedBeforeChange(CandleSeries series, PnFCandle candle, ICandleBuilderSourceValue value)
        {
            var argSize = candle.PnFArg.BoxSize * candle.PnFArg.ReversalAmount;

            if (candle.Type == PnFTypes.X)
            {
                return(candle.ClosePrice - argSize > value.Price);
            }
            else
            {
                return(candle.ClosePrice + argSize < value.Price);
            }
        }
コード例 #9
0
 /// <summary>
 /// Сформирована ли свеча до добавления данных.
 /// </summary>
 /// <param name="series">Серия свечек.</param>
 /// <param name="candle">Свеча.</param>
 /// <param name="value">Данные, с помощью которых принимается решение о необходимости окончания формирования текущей свечи.</param>
 /// <returns><see langword="true"/>, если свечу необходимо закончить. Иначе, <see langword="false"/>.</returns>
 protected override bool IsCandleFinishedBeforeChange(CandleSeries series, TimeFrameCandle candle, ICandleBuilderSourceValue value)
 {
     return(value.Time < candle.OpenTime || (candle.OpenTime + candle.TimeFrame) <= value.Time);
 }
コード例 #10
0
        /// <summary>
        /// Обработать новые данные.
        /// </summary>
        /// <param name="series">Серия свечек.</param>
        /// <param name="currentCandle">Текущая свеча.</param>
        /// <param name="value">Новые данные, с помощью которых принимается решение о необходимости начала или окончания формирования текущей свечи.</param>
        /// <returns>Новая свеча. Если новую свечу нет необходимости создавать, то возвращается <paramref name="currentCandle"/>.
        /// Если новую свечу создать невозможно (<paramref name="value"/> не может быть применено к свечам), то возвращается null.</returns>
        protected virtual TCandle ProcessValue(CandleSeries series, TCandle currentCandle, ICandleBuilderSourceValue value)
        {
            if (currentCandle == null || IsCandleFinishedBeforeChange(series, currentCandle, value))
            {
                currentCandle = CreateCandle(series, value);
                this.AddDebugLog("NewCandle {0} ForValue {1}", currentCandle, value);
                return(currentCandle);
            }

            UpdateCandle(series, currentCandle, value);
            this.AddDebugLog("UpdatedCandle {0} ForValue {1}", currentCandle, value);

            return(currentCandle);
        }
コード例 #11
0
        /// <summary>
        /// Заполнить первоначальные параметры свечи.
        /// </summary>
        /// <param name="series">Серия свечек.</param>
        /// <param name="candle">Свеча.</param>
        /// <param name="value">Данные.</param>
        /// <returns>Свеча.</returns>
        protected virtual TCandle FirstInitCandle(CandleSeries series, TCandle candle, ICandleBuilderSourceValue value)
        {
            if (candle == null)
            {
                throw new ArgumentNullException("candle");
            }

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

            candle.Security = value.Security;

            candle.OpenPrice  = value.Price;
            candle.ClosePrice = value.Price;
            candle.LowPrice   = value.Price;
            candle.HighPrice  = value.Price;
            //candle.TotalPrice = value.Price;

            candle.OpenVolume  = value.Volume;
            candle.CloseVolume = value.Volume;
            candle.LowVolume   = value.Volume;
            candle.HighVolume  = value.Volume;
            //candle.TotalVolume = value.Volume;

            return(candle);
        }
コード例 #12
0
 /// <summary>
 /// Сформирована ли свеча до добавления данных.
 /// </summary>
 /// <param name="series">Серия свечек.</param>
 /// <param name="candle">Свеча.</param>
 /// <param name="value">Данные, с помощью которых принимается решение о необходимости окончания формирования текущей свечи.</param>
 /// <returns><see langword="true"/>, если свечу необходимо закончить. Иначе, <see langword="false"/>.</returns>
 protected virtual bool IsCandleFinishedBeforeChange(CandleSeries series, TCandle candle, ICandleBuilderSourceValue value)
 {
     return(false);
 }
コード例 #13
0
 /// <summary>
 /// Создать новую свечу.
 /// </summary>
 /// <param name="series">Серия свечек.</param>
 /// <param name="value">Данные, с помощью которых необходимо создать новую свечу.</param>
 /// <returns>Созданная свеча.</returns>
 protected virtual TCandle CreateCandle(CandleSeries series, ICandleBuilderSourceValue value)
 {
     throw new NotSupportedException(LocalizedStrings.Str637);
 }
コード例 #14
0
 private static RenkoCandle NewCandle(CandleSeries series, decimal openPrice, decimal closePrice, ICandleBuilderSourceValue value)
 {
     return(new RenkoCandle
     {
         OpenPrice = openPrice,
         ClosePrice = closePrice,
         HighPrice = Math.Max(openPrice, closePrice),
         LowPrice = Math.Min(openPrice, closePrice),
         TotalPrice = openPrice * value.Volume,
         OpenVolume = value.Volume,
         CloseVolume = value.Volume,
         HighVolume = value.Volume,
         LowVolume = value.Volume,
         TotalVolume = value.Volume,
         Security = series.Security,
         OpenTime = value.Time,
         CloseTime = value.Time,
         HighTime = value.Time,
         LowTime = value.Time,
         BoxSize = (Unit)series.Arg,
         RelativeVolume = value.OrderDirection == null ? 0 : (value.OrderDirection == Sides.Buy ? value.Volume : -value.Volume)
     });
 }
コード例 #15
0
        /// <summary>
        /// Обработать новые данные.
        /// </summary>
        /// <param name="series">Серия свечек.</param>
        /// <param name="currentCandle">Текущая свеча.</param>
        /// <param name="value">Новые данные, с помощью которых принимается решение о необходимости начала или окончания формирования текущей свечи.</param>
        /// <returns>Новая свеча. Если новую свечу нет необходимости создавать, то возвращается <paramref name="currentCandle"/>.
        /// Если новую свечу создать невозможно (<paramref name="value"/> не может быть применено к свечам), то возвращается null.</returns>
        protected override RenkoCandle ProcessValue(CandleSeries series, RenkoCandle currentCandle, ICandleBuilderSourceValue value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            if (currentCandle == null)
            {
                return(NewCandle(series, value.Price, value.Price, value));
            }

            var delta = currentCandle.BoxSize.Value;

            if (currentCandle.OpenPrice < currentCandle.ClosePrice)
            {
                if ((value.Price - currentCandle.ClosePrice) > delta)
                {
                    // New bullish candle
                    return(NewCandle(series, currentCandle.ClosePrice, currentCandle.ClosePrice + delta, value));
                }

                if ((currentCandle.OpenPrice - value.Price) > delta)
                {
                    // New bearish candle
                    return(NewCandle(series, currentCandle.OpenPrice, currentCandle.OpenPrice - delta, value));
                }
            }
            else
            {
                if ((value.Price - currentCandle.OpenPrice) > delta)
                {
                    // New bullish candle
                    return(NewCandle(series, currentCandle.OpenPrice, currentCandle.OpenPrice + delta, value));
                }

                if ((currentCandle.ClosePrice - value.Price) > delta)
                {
                    // New bearish candle
                    return(NewCandle(series, currentCandle.ClosePrice, currentCandle.ClosePrice - delta, value));
                }
            }

            return(UpdateRenkoCandle(currentCandle, value));
        }
コード例 #16
0
ファイル: VolumeProfile.cs プロジェクト: zjxbetter/StockSharp
		/// <summary>
		/// To update the profile with new value.
		/// </summary>
		/// <param name="value">Value.</param>
		public void Update(ICandleBuilderSourceValue value)
		{
			if (value.OrderDirection == null)
				return;

			UpdatePriceLevel(GetPriceLevel(value.Price), value);
		}
コード例 #17
0
		/// <summary>
		/// To add data for the candle.
		/// </summary>
		/// <param name="series">Candles series.</param>
		/// <param name="candle">The candle for which you need to add data.</param>
		/// <param name="value">New data.</param>
		public void AddValue(CandleSeries series, Candle candle, ICandleBuilderSourceValue value)
		{
			if (_valuesKeepTime == TimeSpan.Zero)
			    return;

			GetInfo(series).AddValue(candle, value);
		}
コード例 #18
0
 /// <summary>
 /// Сформирована ли свеча до добавления данных.
 /// </summary>
 /// <param name="series">Серия свечек.</param>
 /// <param name="candle">Свеча.</param>
 /// <param name="value">Данные, с помощью которых принимается решение о необходимости окончания формирования текущей свечи.</param>
 /// <returns><see langword="true"/>, если свечу необходимо закончить. Иначе, <see langword="false"/>.</returns>
 protected override bool IsCandleFinishedBeforeChange(CandleSeries series, TickCandle candle, ICandleBuilderSourceValue value)
 {
     return(candle.CurrentTradeCount >= candle.MaxTradeCount);
 }
コード例 #19
0
        /// <summary>
        /// To process the new data.
        /// </summary>
        /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
        /// <param name="currentCandle">The current candle.</param>
        /// <param name="value">The new data by which it is decided to start or end the current candle creation.</param>
        /// <returns>A new candle. If there is not necessary to create a new candle, then <paramref name="currentCandle" /> is returned. If it is impossible to create a new candle (<paramref name="value" /> cannot be applied to candles), then <see langword="null" /> is returned.</returns>
        protected virtual TCandleMessage ProcessValue(MarketDataMessage message, TCandleMessage currentCandle, ICandleBuilderSourceValue value)
        {
            if (currentCandle == null || IsCandleFinishedBeforeChange(message, currentCandle, value))
            {
                currentCandle = CreateCandle(message, currentCandle, value);
                this.AddDebugLog("NewCandle {0} ForValue {1}", currentCandle, value);
                return(currentCandle);
            }

            UpdateCandle(message, currentCandle, value);

            // TODO performance
            //this.AddDebugLog("UpdatedCandle {0} ForValue {1}", currentCandle, value);

            return(currentCandle);
        }
コード例 #20
0
 /// <summary>
 /// Обновить свечу данными.
 /// </summary>
 /// <param name="series">Серия свечек.</param>
 /// <param name="candle">Свеча.</param>
 /// <param name="value">Данные.</param>
 protected override void UpdateCandle(CandleSeries series, TickCandle candle, ICandleBuilderSourceValue value)
 {
     base.UpdateCandle(series, candle, value);
     candle.CurrentTradeCount++;
 }
コード例 #21
0
 /// <summary>
 /// Whether the candle is created before data adding.
 /// </summary>
 /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
 /// <param name="candle">Candle.</param>
 /// <param name="value">Data by which it is decided to end the current candle creation.</param>
 /// <returns><see langword="true" /> if the candle should be finished. Otherwise, <see langword="false" />.</returns>
 protected override bool IsCandleFinishedBeforeChange(MarketDataMessage message, TimeFrameCandleMessage candle, ICandleBuilderSourceValue value)
 {
     return(value.Time < candle.OpenTime || (candle.OpenTime + candle.TimeFrame) <= value.Time);
 }
コード例 #22
0
        /// <summary>
        /// To process the new data.
        /// </summary>
        /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
        /// <param name="currentCandle">The current candle.</param>
        /// <param name="value">The new data by which it is decided to start or end the current candle creation.</param>
        /// <returns>A new candles changes.</returns>
        public IEnumerable <CandleMessage> Process(MarketDataMessage message, CandleMessage currentCandle, ICandleBuilderSourceValue value)
        {
            var changes = new List <CandleMessage>();

            Process(message, currentCandle, value, changes);

            return(changes);
        }
コード例 #23
0
 /// <summary>
 /// Whether the candle is created before data adding.
 /// </summary>
 /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
 /// <param name="candle">Candle.</param>
 /// <param name="value">Data by which it is decided to end the current candle creation.</param>
 /// <returns><see langword="true" /> if the candle should be finished. Otherwise, <see langword="false" />.</returns>
 protected override bool IsCandleFinishedBeforeChange(MarketDataMessage message, TickCandleMessage candle, ICandleBuilderSourceValue value)
 {
     return(candle.TotalTicks != null && candle.TotalTicks.Value >= candle.MaxTradeCount);
 }
コード例 #24
0
        /// <inheritdoc />
        public override void Process(MarketDataMessage message, CandleMessage currentCandle, ICandleBuilderSourceValue value, IList <CandleMessage> changes)
        {
            var currentPnFCandle = (PnFCandleMessage)currentCandle;

            var price  = value.Price;
            var volume = value.Volume;
            var time   = value.Time;
            var side   = value.OrderDirection;
            var pnf    = (PnFArg)message.Arg;

            var pnfStep = (decimal)(1 * pnf.BoxSize);

            if (currentPnFCandle == null)
            {
                var openPrice = MathHelper.Floor(price, pnfStep);
                var highPrice = openPrice + pnfStep;

                changes.Add(CreateCandle(message, pnf, openPrice, highPrice, openPrice, highPrice, price, volume, side, time));
            }
            else
            {
                if (currentPnFCandle.LowPrice <= price && price <= currentPnFCandle.HighPrice)
                {
                    UpdateCandle(currentPnFCandle, price, volume, time, side);
                    changes.Add(currentPnFCandle);
                }
                else
                {
                    var isX = currentPnFCandle.OpenPrice < currentPnFCandle.ClosePrice;

                    if (isX)
                    {
                        if (price > currentPnFCandle.HighPrice)
                        {
                            currentPnFCandle.HighPrice = currentPnFCandle.ClosePrice = MathHelper.Floor(price, pnfStep) + pnfStep;
                            UpdateCandle(currentPnFCandle, price, volume, time, side);
                            changes.Add(currentPnFCandle);
                        }
                        else if (price < (currentPnFCandle.HighPrice - pnfStep * pnf.ReversalAmount))
                        {
                            currentPnFCandle.State = CandleStates.Finished;
                            changes.Add(currentPnFCandle);

                            var highPrice = currentPnFCandle.HighPrice - pnfStep;
                            var lowPrice  = MathHelper.Floor(price, pnfStep);

                            currentPnFCandle = CreateCandle(message, pnf, highPrice, highPrice, lowPrice, lowPrice, price, volume, side, time);
                            changes.Add(currentPnFCandle);
                        }
                        else
                        {
                            UpdateCandle(currentPnFCandle, price, volume, time, side);
                            changes.Add(currentPnFCandle);
                        }
                    }
                    else
                    {
                        if (price < currentPnFCandle.LowPrice)
                        {
                            currentPnFCandle.LowPrice = currentPnFCandle.ClosePrice = MathHelper.Floor(price, pnfStep);
                            UpdateCandle(currentPnFCandle, price, volume, time, side);
                            changes.Add(currentPnFCandle);
                        }
                        else if (price > (currentPnFCandle.LowPrice + pnfStep * pnf.ReversalAmount))
                        {
                            currentPnFCandle.State = CandleStates.Finished;
                            changes.Add(currentPnFCandle);

                            var highPrice = MathHelper.Floor(price, pnfStep) + pnfStep;
                            var lowPrice  = currentPnFCandle.LowPrice + pnfStep;

                            currentPnFCandle = CreateCandle(message, pnf, lowPrice, highPrice, lowPrice, highPrice, price, volume, side, time);
                            changes.Add(currentPnFCandle);
                        }
                        else
                        {
                            UpdateCandle(currentPnFCandle, price, volume, time, side);
                            changes.Add(currentPnFCandle);
                        }
                    }
                }
            }
        }
コード例 #25
0
 /// <summary>
 /// To create a new candle.
 /// </summary>
 /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
 /// <param name="currentCandle">The current candle.</param>
 /// <param name="value">Data with which a new candle should be created.</param>
 /// <returns>Created candle.</returns>
 protected override VolumeCandleMessage CreateCandle(MarketDataMessage message, VolumeCandleMessage currentCandle, ICandleBuilderSourceValue value)
 {
     return(FirstInitCandle(message, new VolumeCandleMessage
     {
         Volume = (decimal)message.Arg,
         OpenTime = value.Time,
         CloseTime = value.Time,
         HighTime = value.Time,
         LowTime = value.Time,
     }, value));
 }
コード例 #26
0
        /// <summary>
        /// To process the new data.
        /// </summary>
        /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
        /// <param name="currentCandle">The current candle.</param>
        /// <param name="value">The new data by which it is decided to start or end the current candle creation.</param>
        /// <param name="changes">A new candles changes.</param>
        public virtual void Process(MarketDataMessage message, CandleMessage currentCandle, ICandleBuilderSourceValue value, IList <CandleMessage> changes)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

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

            var candle = ProcessValue(message, (TCandleMessage)currentCandle, value);

            if (candle == null)
            {
                // skip the value that cannot be processed
                return;
            }

            if (candle == currentCandle)
            {
                if (message.IsCalcVolumeProfile)
                {
                    if (candle.VolumeProfile == null)
                    {
                        throw new InvalidOperationException();
                    }

                    candle.VolumeProfile.Update(value);
                }

                //candle.State = CandleStates.Changed;
                changes.Add(candle);
            }
            else
            {
                if (currentCandle != null)
                {
                    currentCandle.State = CandleStates.Finished;
                    changes.Add(currentCandle);
                }

                if (message.IsCalcVolumeProfile)
                {
                    candle.VolumeProfile = new CandleMessageVolumeProfile();
                    candle.VolumeProfile.Update(value);
                }

                candle.State = CandleStates.Active;
                changes.Add(candle);
            }
        }
コード例 #27
0
 /// <summary>
 /// To create a new candle.
 /// </summary>
 /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
 /// <param name="currentCandle">The current candle.</param>
 /// <param name="value">Data with which a new candle should be created.</param>
 /// <returns>Created candle.</returns>
 protected override RangeCandleMessage CreateCandle(MarketDataMessage message, RangeCandleMessage currentCandle, ICandleBuilderSourceValue value)
 {
     return(FirstInitCandle(message, new RangeCandleMessage
     {
         PriceRange = (Unit)message.Arg,
         OpenTime = value.Time,
         CloseTime = value.Time,
         HighTime = value.Time,
         LowTime = value.Time,
     }, value));
 }
コード例 #28
0
        /// <inheritdoc />
        public override void Process(MarketDataMessage message, CandleMessage currentCandle, ICandleBuilderSourceValue value, IList <CandleMessage> changes)
        {
            var currentRenkoCandle = (RenkoCandleMessage)currentCandle;

            var price   = value.Price;
            var volume  = value.Volume;
            var time    = value.Time;
            var side    = value.OrderDirection;
            var boxSize = (Unit)message.Arg;

            var renkoStep = (decimal)(1 * boxSize);

            if (currentRenkoCandle == null)
            {
                var openPrice = MathHelper.Floor(price, renkoStep);

                changes.Add(CreateCandle(message, boxSize, openPrice, renkoStep, price, volume, side, time));
            }
            else
            {
                if (currentRenkoCandle.LowPrice <= price && price <= currentRenkoCandle.HighPrice)
                {
                    currentRenkoCandle.TotalTicks++;

                    if (volume != null)
                    {
                        currentRenkoCandle.TotalVolume += volume.Value;
                        currentRenkoCandle.TotalPrice  += volume.Value * price;

                        currentRenkoCandle.RelativeVolume += side == Sides.Buy ? volume : -volume;
                    }

                    currentRenkoCandle.CloseVolume = volume;
                    currentRenkoCandle.CloseTime   = time;

                    currentRenkoCandle.VolumeProfile?.Update(price, volume, side);

                    changes.Add(currentRenkoCandle);
                }
                else
                {
                    currentRenkoCandle.State = CandleStates.Finished;
                    changes.Add(currentRenkoCandle);

                    int     times;
                    bool    isUp;
                    decimal openPrice;

                    if (price < currentRenkoCandle.LowPrice)
                    {
                        times     = (int)((currentRenkoCandle.LowPrice - price) / renkoStep) + 1;
                        isUp      = false;
                        openPrice = currentRenkoCandle.LowPrice;
                    }
                    else
                    {
                        times     = (int)((price - currentRenkoCandle.HighPrice) / renkoStep) + 1;
                        isUp      = true;
                        openPrice = currentRenkoCandle.HighPrice;
                    }

                    for (var i = 0; i < times; i++)
                    {
                        if (isUp)
                        {
                            currentRenkoCandle = CreateCandle(message, boxSize, openPrice, renkoStep, price, volume, side, time);
                            changes.Add(currentRenkoCandle);
                            openPrice += renkoStep;
                        }
                        else
                        {
                            currentRenkoCandle = CreateCandle(message, boxSize, openPrice, -renkoStep, price, volume, side, time);
                            changes.Add(currentRenkoCandle);
                            openPrice -= renkoStep;
                        }

                        currentRenkoCandle.State = CandleStates.Finished;
                    }

                    currentRenkoCandle.State = CandleStates.Active;
                }
            }
        }
コード例 #29
0
        /// <summary>
        /// To process the new data.
        /// </summary>
        /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
        /// <param name="value">The new data by which it is decided to start or end the current candle creation.</param>
        /// <returns>A new candles changes.</returns>
        public IEnumerable <CandleMessage> Process(MarketDataMessage message, ICandleBuilderSourceValue value)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

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

            var info = _info.SafeAdd(message, k => new CandleInfo());

            if (info == null)
            {
                yield break;
            }

            var currCandle = info.CurrentCandle;

            var candle = ProcessValue(message, (TCandleMessage)currCandle, value);

            if (candle == null)
            {
                // skip the value that cannot be processed
                yield break;
            }

            if (candle == currCandle)
            {
                if (message.IsCalcVolumeProfile)
                {
                    if (info.VolumeProfile == null)
                    {
                        throw new InvalidOperationException();
                    }

                    info.VolumeProfile.Update(value);
                }

                //candle.State = CandleStates.Changed;
                yield return(candle);
            }
            else
            {
                if (currCandle != null)
                {
                    info.CurrentCandle = null;
                    info.VolumeProfile = null;

                    currCandle.State = CandleStates.Finished;
                    yield return(currCandle);
                }

                info.CurrentCandle = candle;

                if (message.IsCalcVolumeProfile)
                {
                    info.VolumeProfile = new VolumeProfile();
                    info.VolumeProfile.Update(value);

                    candle.PriceLevels = info.VolumeProfile.PriceLevels;
                }

                candle.State = CandleStates.Active;
                yield return(candle);
            }
        }
コード例 #30
0
 /// <summary>
 /// To create a new candle.
 /// </summary>
 /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
 /// <param name="currentCandle">The current candle.</param>
 /// <param name="value">Data with which a new candle should be created.</param>
 /// <returns>Created candle.</returns>
 protected virtual TCandleMessage CreateCandle(MarketDataMessage message, TCandleMessage currentCandle, ICandleBuilderSourceValue value)
 {
     throw new NotSupportedException(LocalizedStrings.Str637);
 }
コード例 #31
0
ファイル: VolumeProfile.cs プロジェクト: zjxbetter/StockSharp
		private void UpdatePriceLevel(CandlePriceLevel level, ICandleBuilderSourceValue value)
		{
			if (level == null)
				throw new ArgumentNullException(nameof(level));

			var side = value.OrderDirection;

			if (side == null)
				throw new ArgumentException(nameof(value));

			if (side == Sides.Buy)
			{
				level.BuyVolume += value.Volume;
				level.BuyCount++;

				((List<decimal>)level.BuyVolumes).Add(value.Volume);
			}
			else
			{
				level.SellVolume += value.Volume;
				level.SellCount++;

				((List<decimal>)level.SellVolumes).Add(value.Volume);
			}
		}
コード例 #32
0
 /// <summary>
 /// Whether the candle is created before data adding.
 /// </summary>
 /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
 /// <param name="candle">Candle.</param>
 /// <param name="value">Data by which it is decided to end the current candle creation.</param>
 /// <returns><see langword="true" /> if the candle should be finished. Otherwise, <see langword="false" />.</returns>
 protected virtual bool IsCandleFinishedBeforeChange(MarketDataMessage message, TCandleMessage candle, ICandleBuilderSourceValue value)
 {
     return(false);
 }
コード例 #33
0
        /// <summary>
        /// To fill in the initial candle settings.
        /// </summary>
        /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
        /// <param name="candle">Candle.</param>
        /// <param name="value">Data.</param>
        /// <returns>Candle.</returns>
        protected virtual TCandleMessage FirstInitCandle(MarketDataMessage message, TCandleMessage candle, ICandleBuilderSourceValue value)
        {
            if (candle == null)
            {
                throw new ArgumentNullException(nameof(candle));
            }

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

            candle.SecurityId = message.SecurityId;

            candle.OpenPrice  = value.Price;
            candle.ClosePrice = value.Price;
            candle.LowPrice   = value.Price;
            candle.HighPrice  = value.Price;
            //candle.TotalPrice = value.Price;

            candle.OpenVolume  = value.Volume;
            candle.CloseVolume = value.Volume;
            candle.LowVolume   = value.Volume;
            candle.HighVolume  = value.Volume;
            candle.TotalVolume = value.Volume ?? 0;

            return(candle);
        }
コード例 #34
0
        /// <summary>
        /// To update the candle data.
        /// </summary>
        /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
        /// <param name="candle">Candle.</param>
        /// <param name="value">Data.</param>
        protected virtual void UpdateCandle(MarketDataMessage message, TCandleMessage candle, ICandleBuilderSourceValue value)
        {
            if (candle == null)
            {
                throw new ArgumentNullException(nameof(candle));
            }

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

            Update(candle, value);
        }
コード例 #35
0
			public void AddValue(Candle candle, ICandleBuilderSourceValue value)
			{
				if (candle == null)
					throw new ArgumentNullException("candle");

				if (value == null)
					throw new ArgumentNullException("value");

				_candleValues.SafeAdd(candle).AddLast(value);
				_valuesStat.Add(value);

				if (_firstValueTime == 0)
					_firstValueTime = value.Time.UtcTicks;

				_lastValueTime = value.Time.UtcTicks;

				RecycleValues();
			}
コード例 #36
0
        /// <summary>
        /// Создать новую свечу.
        /// </summary>
        /// <param name="series">Серия свечек.</param>
        /// <param name="value">Данные, с помощью которых необходимо создать новую свечу.</param>
        /// <returns>Созданная свеча.</returns>
        protected override PnFCandle CreateCandle(CandleSeries series, ICandleBuilderSourceValue value)
        {
            var arg     = (PnFArg)series.Arg;
            var boxSize = arg.BoxSize;

            if (CandleManager == null)
            {
                throw new InvalidOperationException(LocalizedStrings.CandleManagerIsNotSet);
            }

            var pnfCandle = (PnFCandle)CandleManager.Container.GetCandle(series, 0);

            var candle = new PnFCandle
            {
                PnFArg    = arg,
                OpenTime  = value.Time,
                CloseTime = value.Time,
                HighTime  = value.Time,
                LowTime   = value.Time,

                Security = value.Security,

                OpenVolume  = value.Volume,
                CloseVolume = value.Volume,
                LowVolume   = value.Volume,
                HighVolume  = value.Volume,
                TotalVolume = value.Volume,

                TotalPrice = value.Price * value.Volume,

                Type = pnfCandle == null ? PnFTypes.X : (pnfCandle.Type == PnFTypes.X ? PnFTypes.O : PnFTypes.X),
            };

            if (pnfCandle == null)
            {
                candle.OpenPrice = boxSize.AlignPrice(value.Price, value.Price);

                if (candle.Type == PnFTypes.X)
                {
                    candle.ClosePrice = (decimal)(candle.OpenPrice + boxSize);
                }
                else
                {
                    candle.ClosePrice = (decimal)(candle.OpenPrice - boxSize);
                }
            }
            else
            {
                candle.OpenPrice = (decimal)((pnfCandle.Type == PnFTypes.X)
                                        ? pnfCandle.ClosePrice - boxSize
                                        : pnfCandle.ClosePrice + boxSize);

                var price = boxSize.AlignPrice(candle.OpenPrice, value.Price);

                if (candle.Type == PnFTypes.X)
                {
                    candle.ClosePrice = (decimal)(price + boxSize);
                }
                else
                {
                    candle.ClosePrice = (decimal)(price - boxSize);
                }
            }

            if (candle.Type == PnFTypes.X)
            {
                candle.LowPrice  = candle.OpenPrice;
                candle.HighPrice = candle.ClosePrice;
            }
            else
            {
                candle.LowPrice  = candle.ClosePrice;
                candle.HighPrice = candle.OpenPrice;
            }

            return(candle);
        }