/// <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; } }