Lean  $LEAN_TAG$
StochasticRelativeStrengthIndex.cs
1 /*
2  * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3  * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14 */
15 
16 using System;
17 using System.Linq;
18 
20 {
21  /// <summary>
22  /// Stochastic RSI, or simply StochRSI, is a technical analysis indicator used to determine whether
23  /// an asset is overbought or oversold, as well as to identify current market trends.
24  /// As the name suggests, the StochRSI is a derivative of the standard Relative Strength Index (RSI) and,
25  /// as such, is considered an indicator of an indicator.
26  /// It is a type of oscillator, meaning that it fluctuates above and below a center line.
27  /// </summary>
29  {
30  private readonly RelativeStrengthIndex _rsi;
31  private readonly RollingWindow<decimal> _recentRSIValues;
32 
33  /// <summary>
34  /// Gets the %K output
35  /// </summary>
37 
38  /// <summary>
39  /// Gets the %D output
40  /// </summary>
42 
43  /// <summary>
44  /// Gets a flag indicating when this indicator is ready and fully initialized
45  /// </summary>
46  public override bool IsReady => Samples >= WarmUpPeriod;
47 
48  /// <summary>
49  /// Required period, in data points, for the indicator to be ready and fully initialized.
50  /// </summary>
51  public int WarmUpPeriod { get; }
52 
53  /// <summary>
54  /// Initializes a new instance of the StochasticRelativeStrengthIndex class
55  /// </summary>
56  /// <param name="rsiPeriod">The period of the relative strength index</param>
57  /// <param name="stochPeriod">The period of the stochastic indicator</param>
58  /// <param name="kSmoothingPeriod">The smoothing period of K output (aka %K)</param>
59  /// <param name="dSmoothingPeriod">The smoothing period of D output (aka %D)</param>
60  /// <param name="movingAverageType">The type of moving average to be used for k and d</param>
61  public StochasticRelativeStrengthIndex(int rsiPeriod, int stochPeriod, int kSmoothingPeriod, int dSmoothingPeriod, MovingAverageType movingAverageType = MovingAverageType.Simple)
62  : this($"SRSI({rsiPeriod},{stochPeriod},{kSmoothingPeriod},{dSmoothingPeriod},{movingAverageType})", rsiPeriod, stochPeriod, kSmoothingPeriod, dSmoothingPeriod, movingAverageType)
63  {
64  }
65 
66  /// <summary>
67  /// Initializes a new instance of the StochasticRelativeStrengthIndex class
68  /// </summary>
69  /// <param name="name">The name of this indicator</param>
70  /// <param name="rsiPeriod">The period of the relative strength index</param>
71  /// <param name="stochPeriod">The period of the stochastic indicator</param>
72  /// <param name="kSmoothingPeriod">The smoothing period of K output</param>
73  /// <param name="dSmoothingPeriod">The smoothing period of D output</param>
74  /// <param name="movingAverageType">The type of moving average to be used</param>
75  public StochasticRelativeStrengthIndex(string name, int rsiPeriod, int stochPeriod, int kSmoothingPeriod, int dSmoothingPeriod, MovingAverageType movingAverageType = MovingAverageType.Simple)
76  : base(name)
77  {
78  _rsi = new RelativeStrengthIndex(rsiPeriod);
79  _recentRSIValues = new RollingWindow<decimal>(stochPeriod);
80 
81  K = movingAverageType.AsIndicator($"{name}_K_{movingAverageType}", kSmoothingPeriod);
82  D = movingAverageType.AsIndicator($"{name}_D_{movingAverageType}", dSmoothingPeriod);
83 
84  WarmUpPeriod = rsiPeriod + stochPeriod + Math.Max(kSmoothingPeriod, dSmoothingPeriod);
85  }
86 
87  /// <summary>
88  /// Computes the next value of the following sub-indicators from the given state:
89  /// K (%K) and D (%D)
90  /// </summary>
91  /// <param name="input">The input given to the indicator</param>
92  /// <returns>The input is returned unmodified.</returns>
93  protected override decimal ComputeNextValue(IndicatorDataPoint input)
94  {
95  _rsi.Update(input);
96  _recentRSIValues.Add(_rsi.Current.Value);
97 
98  if (!_recentRSIValues.IsReady)
99  {
100  return 0m;
101  }
102 
103  var maxHigh = _recentRSIValues.Max();
104  var minLow = _recentRSIValues.Min();
105 
106  decimal k = 100;
107  if (maxHigh != minLow)
108  {
109  k = 100 * (_rsi.Current.Value - minLow) / (maxHigh - minLow);
110  }
111 
112  K.Update(input.EndTime, k);
113  D.Update(input.EndTime, K.Current.Value);
114 
115  return input.Value;
116  }
117 
118  /// <summary>
119  /// Resets this indicator and all sub-indicators
120  /// </summary>
121  public override void Reset()
122  {
123  _rsi.Reset();
124  _recentRSIValues.Reset();
125  K.Reset();
126  D.Reset();
127  base.Reset();
128  }
129  }
130 }