/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace QuantConnect.Indicators { /// /// Represents the Derivative Oscillator Indicator, utilizing /// a moving average convergence-divergence (MACD) histogram to a double-smoothed relative strength index (RSI). /// public class DerivativeOscillator : Indicator, IIndicatorWarmUpPeriodProvider { private readonly RelativeStrengthIndex _rsi; private readonly ExponentialMovingAverage _smoothedRsi; private readonly ExponentialMovingAverage _doubleSmoothedRsi; private readonly SimpleMovingAverage _signalLine; /// /// Gets a flag indicating when this indicator is ready and fully initialized /// public override bool IsReady => _signalLine.IsReady; /// /// Required period, in data points, for the indicator to be ready and fully initialized. /// public int WarmUpPeriod { get; } /// /// Initializes a new instance of the IndicatorDerivativeOscillator class with the specified name and periods. /// /// The name of the indicator /// The period for the RSI calculation /// The period for the smoothing RSI /// The period for the double smoothing RSI /// The period for the signal line public DerivativeOscillator(string name, int rsiPeriod, int smoothingRsiPeriod, int doubleSmoothingRsiPeriod, int signalLinePeriod) : base(name) { _rsi = new RelativeStrengthIndex($"{name}_RSI", rsiPeriod); _smoothedRsi = new ExponentialMovingAverage($"{name}_SmoothedRSI", smoothingRsiPeriod).Of(_rsi); _doubleSmoothedRsi = new ExponentialMovingAverage($"{name}_DoubleSmoothedRSI", doubleSmoothingRsiPeriod).Of(_smoothedRsi); _signalLine = new SimpleMovingAverage($"{name}_SignalLine", signalLinePeriod).Of(_doubleSmoothedRsi); WarmUpPeriod = (rsiPeriod + smoothingRsiPeriod + doubleSmoothingRsiPeriod + signalLinePeriod - 3) + 1; } /// /// Computes the next value for the derivative oscillator indicator from the given state /// /// The input value to this indicator on this time step /// A new value for this indicator protected override decimal ComputeNextValue(IndicatorDataPoint input) { // Chaining updates all of the other indicators _rsi.Update(input); if (!IsReady) { return 0; } return _doubleSmoothedRsi.Current.Value - _signalLine.Current.Value; } /// /// Resets this indicator to its initial state /// public override void Reset() { _rsi.Reset(); _smoothedRsi.Reset(); _doubleSmoothedRsi.Reset(); _signalLine.Reset(); base.Reset(); } } }