PaintbarsDataSeries - bar colours

The DataSeries which allows setting colour for each bar. Each element of this DataSeries is a nullable Color.

It has one property (Visible) which regulates the DataSeries visibility.


Example of the HeikenAshi indicator, which uses this DataSeries. The PaintbarsDataSeries performs here the function of hiding standard bars with the help of setting a transparent colour.

public class HeikenAshi:Indicator
    {
        readonly CandleDataSeries _candles=new CandleDataSeries("Heiken Ashi");
        readonly PaintbarsDataSeries _bars= new PaintbarsDataSeries("Bars"){IsHidden = true};
        
        public HeikenAshi():base(true)
        {
            DenyToChangePanel = true;
            DataSeries[0]= _bars;
            DataSeries.Add(_candles);
        }

        protected override void OnCalculate(int bar, decimal value)
        {
            var candle = GetCandle(bar);
            _bars[bar] = Colors.Transparent;

            if (bar == 0)
            {
                _candles[bar] = new Candle()
                {
                    Close = candle.Close,
                    High = candle.High,
                    Low = candle.Low,
                    Open = candle.Open
                };
            }
            else
            {
                var prevCandle = _candles[bar - 1];
                var close = (candle.Open + candle.Close + candle.High + candle.Low) * 0.25m;
                var open = (prevCandle.Open + prevCandle.Close) * 0.5m;
                var high = Math.Max(Math.Max(close, open), candle.High);
                var low = Math.Min(Math.Min(close, open), candle.Low);
                _candles[bar] = new Candle()
                {
                    Close = close,
                    High = high,
                    Low = low,
                    Open = open,
                };
            }
            
        }
    }

Example of the Bar’s Volume Filter indicator which colours bars depending on their volumes.

[DisplayName("Bar's volume filter")]
    public class BarVolumeFilter : Indicator
    {
        #region Nested types

        public enum VolumeType
        {
            Volume,
            Ticks,
            Delta,
            Bid,
            Ask
        }

        #endregion

        private readonly PaintbarsDataSeries _paintBars = new PaintbarsDataSeries("Paint bars");

        private int _minFilter ;
        private int _maxFilter = 100;
        private System.Windows.Media.Color _color = System.Windows.Media.Colors.Orange;
        private VolumeType _volumeType;

        [Name = "Type", Order = 5)]
        public VolumeType Type
        {
            get => _volumeType;
            set { _volumeType = value; RecalculateValues(); }
        }

        [Display(Name = "Minimum", Order = 10)]
        public int MinFilter
        {
            get => _minFilter;
            set { _minFilter = value;RecalculateValues(); }
        }

        [Display(Name = "Maximum", Order = 20)]
        public int MaxFilter
        {
            get => _maxFilter;
            set { _maxFilter = value; RecalculateValues(); }
        }

        [Name = "Color", Order = 30)]
        public System.Windows.Media.Color FilterColor
        {
            get => _color;
            set { _color = value; RecalculateValues(); }
        }

        public BarVolumeFilter():base(true)
        {
            DataSeries[0] = _paintBars;
            _paintBars.IsHidden = true;
            DenyToChangePanel = true;
        }

        #region Overrides of BaseIndicator

        protected override void OnCalculate(int bar, decimal value)
        {
            var candle = GetCandle(bar);
            decimal volume = 0;

            switch (Type)
            {
                case VolumeType.Volume:
                {
                    volume = candle.Volume;
                    break;
                }
                case VolumeType.Ticks:
                {
                    volume = candle.Ticks;
                    break;
                }
                case VolumeType.Delta:
                {
                    volume = candle.Delta;
                    break;
                }
                case VolumeType.Bid:
                {
                    volume = candle.Bid;
                    break;
                }
                case VolumeType.Ask:
                {
                    volume = candle.Ask;
                    break;
                }
                default:
                    throw new ArgumentOutOfRangeException();
            }

            if (volume > _minFilter && volume <= _maxFilter)
            {
                _paintBars[bar] = _color;
            }
            else
            {
                _paintBars[bar] = null;
            }
        }

        #endregion
    }