/*
* 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();
}
}
}