Lean  $LEAN_TAG$
SchaffTrendCycle.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 
19 {
20  /// <summary>
21  /// This indicator creates the Schaff Trend Cycle
22  /// </summary>
24  {
25  // MACD Variables
26  private readonly MovingAverageConvergenceDivergence _MACD;
27  private readonly IndicatorBase<IndicatorDataPoint> _maximum;
28  private readonly IndicatorBase<IndicatorDataPoint> _minimum;
29 
30  // _K = %K FROM MACD; _D = %D FROM _K
31  private readonly IndicatorBase<IndicatorDataPoint> _K;
32  private readonly IndicatorBase<IndicatorDataPoint> _D;
33  private readonly IndicatorBase<IndicatorDataPoint> _maximumD;
34  private readonly IndicatorBase<IndicatorDataPoint> _minimumD;
35 
36  // PF = %K FROM %MACD_D; PFF = %D FROM PF
37  private readonly IndicatorBase<IndicatorDataPoint> _PF;
38  private readonly IndicatorBase<IndicatorDataPoint> _PFF;
39 
40  /// <summary>
41  /// Gets a flag indicating when this indicator is ready and fully initialized
42  /// </summary>
43  public override bool IsReady => _MACD.IsReady;
44 
45  /// <summary>
46  /// Required period, in data points, for the indicator to be ready and fully initialized.
47  /// </summary>
48  public int WarmUpPeriod { get; }
49 
50  /// <summary>
51  /// Creates the name string and calls on the indicator constructor with given parameters
52  /// https://www.tradingpedia.com/forex-trading-indicators/schaff-trend-cycle
53  /// </summary>
54  /// <param name="fastPeriod">The fast moving average period</param>
55  /// <param name="slowPeriod">The slow moving average period</param>
56  /// <param name="cyclePeriod">The signal period</param>
57  /// <param name="type">The type of moving averages to use</param>
58  public SchaffTrendCycle(int cyclePeriod = 10, int fastPeriod = 23, int slowPeriod = 50, MovingAverageType type = MovingAverageType.Exponential)
59  : this($"SchaffTrendCycle({cyclePeriod},{fastPeriod},{slowPeriod})", cyclePeriod, fastPeriod, slowPeriod, type)
60  {
61  }
62 
63  /// <summary>
64  /// Creates a new schaff trend cycle with the specified parameters
65  /// </summary>
66  /// <param name="name">The name of this indicator</param>
67  /// <param name="fastPeriod">The fast moving average period</param>
68  /// <param name="slowPeriod">The slow moving average period</param>
69  /// <param name="cyclePeriod">The signal period</param>
70  /// <param name="type">The type of moving averages to use</param>
71  public SchaffTrendCycle(string name, int cyclePeriod, int fastPeriod, int slowPeriod, MovingAverageType type)
72  : base(name)
73  {
74  //Create MACD indicator and track max and min.
75  _MACD = new MovingAverageConvergenceDivergence(fastPeriod, slowPeriod, cyclePeriod, type);
76  _maximum = _MACD.MAX(cyclePeriod, false);
77  _minimum = _MACD.MIN(cyclePeriod, false);
78 
79  //Stochastics of MACD variables
80  _K = new Identity(name + "_K");
81  _D = type.AsIndicator(3).Of(_K, false);
82  _maximumD = _D.MAX(cyclePeriod, false);
83  _minimumD = _D.MIN(cyclePeriod, false);
84 
85  //Stochastics of MACD Stochastics variables; _PFF is STC
86  _PF = new Identity(name + "_PF");
87  _PFF = type.AsIndicator(3).Of(_PF, false);
88 
89  WarmUpPeriod = _MACD.WarmUpPeriod;
90  }
91 
92  /// <summary>
93  /// Computes the next value of this indicator from the given state
94  /// </summary>
95  /// <param name="input">The input given to the indicator</param>
96  /// <returns>A new value for this indicator</returns>
97  protected override decimal ComputeNextValue(IndicatorDataPoint input)
98  {
99  // Update internal indicator, automatically updates _maximum and _minimum
100  _MACD.Update(input);
101 
102  // Update our Stochastics K, automatically updates our Stochastics D variable which is a smoothed version of K
103  var MACD_K = new IndicatorDataPoint(input.Time, ComputeStoch(_MACD.Current.Value, _maximum.Current.Value, _minimum.Current.Value));
104  _K.Update(MACD_K);
105 
106  // With our Stochastic D values calculate PF
107  var PF = new IndicatorDataPoint(input.Time, ComputeStoch(_D.Current.Value, _maximumD.Current.Value, _minimumD.Current.Value));
108  _PF.Update(PF);
109 
110  return _PFF.Current.Value;
111  }
112 
113  /// <summary>
114  /// Computes the stochastics value for a series.
115  /// </summary>
116  /// <param name="value">The current value of the set</param>
117  /// <param name="highest">The max value of the set within a given period</param>
118  /// <param name="lowest">The min value of the set within a given period</param>
119  /// <returns>Stochastics value </returns>
120  private decimal ComputeStoch(decimal value, decimal highest, decimal lowest)
121  {
122  var numerator = value - lowest;
123  var denominator = highest - lowest;
124 
125  return denominator > 0 ? (numerator / denominator) * 100 : decimal.Zero;
126  }
127 
128  /// <summary>
129  /// Resets this indicator to its initial state
130  /// </summary>
131  public override void Reset()
132  {
133  _MACD.Reset();
134  _maximum.Reset();
135  _minimum.Reset();
136  _K.Reset();
137  _D.Reset();
138  _maximumD.Reset();
139  _minimumD.Reset();
140  _PF.Reset();
141  _PFF.Reset();
142  base.Reset();
143  }
144  }
145 }