/// <summary> /// To process the new data. /// </summary> /// <param name="subscription">Subscription.</param> /// <param name="transform">The data source transformation.</param> /// <returns>A new candles changes.</returns> protected virtual IEnumerable <TCandleMessage> OnProcess(ICandleBuilderSubscription subscription, ICandleBuilderValueTransform transform) { if (subscription is null) { throw new ArgumentNullException(nameof(subscription)); } if (transform == null) { throw new ArgumentNullException(nameof(transform)); } var currentCandle = (TCandleMessage)subscription.CurrentCandle; var volumeProfile = subscription.VolumeProfile; var candle = ProcessValue(subscription, transform); if (candle == null) { // skip the value that cannot be processed yield break; } if (candle == currentCandle) { if (subscription.Message.IsCalcVolumeProfile) { if (volumeProfile == null) { throw new InvalidOperationException(); } volumeProfile.Update(transform); } //candle.State = CandleStates.Changed; yield return(candle); } else { if (currentCandle != null) { currentCandle.State = CandleStates.Finished; yield return(currentCandle); } if (subscription.Message.IsCalcVolumeProfile) { var levels = new List <CandlePriceLevel>(); subscription.VolumeProfile = volumeProfile = new VolumeProfileBuilder(levels); volumeProfile.Update(transform); candle.PriceLevels = levels; } candle.State = CandleStates.Active; yield return(candle); } }
/// <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="transform">The data source transformation.</param> /// <param name="volumeProfile">Volume profile.</param> /// <param name="changes">A new candles changes.</param> public virtual void Process(MarketDataMessage message, CandleMessage currentCandle, ICandleBuilderValueTransform transform, ref VolumeProfileBuilder volumeProfile, IList <CandleMessage> changes) { if (message == null) { throw new ArgumentNullException(nameof(message)); } if (transform == null) { throw new ArgumentNullException(nameof(transform)); } var candle = ProcessValue(message, (TCandleMessage)currentCandle, transform); if (candle == null) { // skip the value that cannot be processed return; } if (candle == currentCandle) { if (message.IsCalcVolumeProfile) { if (volumeProfile == null) { throw new InvalidOperationException(); } volumeProfile.Update(transform); } //candle.State = CandleStates.Changed; changes.Add(candle); } else { if (currentCandle != null) { currentCandle.State = CandleStates.Finished; changes.Add(currentCandle); } if (message.IsCalcVolumeProfile) { var levels = new List <CandlePriceLevel>(); volumeProfile = new VolumeProfileBuilder(levels); volumeProfile.Update(transform); candle.PriceLevels = levels; } candle.State = CandleStates.Active; changes.Add(candle); } }
/// <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 VolumeProfileBuilder 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); }