/// <summary>
        /// The Keltner Channel is a similar indicator to Bollinger Bands. Here the midline is a standard moving average with the upper and lower bands offset by the SMA of the difference between the high and low of the previous bars. The offset multiplier as well as the SMA period is configurable.
        /// </summary>
        /// <returns></returns>
        public KeltnerChannel KeltnerChannel(Data.IDataSeries input, double offsetMultiplier, int period)
        {
            if (cacheKeltnerChannel != null)
                for (int idx = 0; idx < cacheKeltnerChannel.Length; idx++)
                    if (Math.Abs(cacheKeltnerChannel[idx].OffsetMultiplier - offsetMultiplier) <= double.Epsilon && cacheKeltnerChannel[idx].Period == period && cacheKeltnerChannel[idx].EqualsInput(input))
                        return cacheKeltnerChannel[idx];

            lock (checkKeltnerChannel)
            {
                checkKeltnerChannel.OffsetMultiplier = offsetMultiplier;
                offsetMultiplier = checkKeltnerChannel.OffsetMultiplier;
                checkKeltnerChannel.Period = period;
                period = checkKeltnerChannel.Period;

                if (cacheKeltnerChannel != null)
                    for (int idx = 0; idx < cacheKeltnerChannel.Length; idx++)
                        if (Math.Abs(cacheKeltnerChannel[idx].OffsetMultiplier - offsetMultiplier) <= double.Epsilon && cacheKeltnerChannel[idx].Period == period && cacheKeltnerChannel[idx].EqualsInput(input))
                            return cacheKeltnerChannel[idx];

                KeltnerChannel indicator = new KeltnerChannel();
                indicator.BarsRequired = BarsRequired;
                indicator.CalculateOnBarClose = CalculateOnBarClose;
#if NT7
                indicator.ForceMaximumBarsLookBack256 = ForceMaximumBarsLookBack256;
                indicator.MaximumBarsLookBack = MaximumBarsLookBack;
#endif
                indicator.Input = input;
                indicator.OffsetMultiplier = offsetMultiplier;
                indicator.Period = period;
                Indicators.Add(indicator);
                indicator.SetUp();

                KeltnerChannel[] tmp = new KeltnerChannel[cacheKeltnerChannel == null ? 1 : cacheKeltnerChannel.Length + 1];
                if (cacheKeltnerChannel != null)
                    cacheKeltnerChannel.CopyTo(tmp, 0);
                tmp[tmp.Length - 1] = indicator;
                cacheKeltnerChannel = tmp;
                return indicator;
            }
        }