Lean  $LEAN_TAG$
ChandeKrollStop.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 
17 
19 {
20  /// <summary>
21  /// This indicator computes the short stop and lower stop values of the Chande Kroll Stop Indicator.
22  /// It is used to determine the optimal placement of a stop-loss order.
23  /// </summary>
25  {
26  private readonly AverageTrueRange _atr;
27  private readonly decimal _atrMult;
28 
29  private readonly Maximum _underlyingMaximum;
30  private readonly Minimum _underlyingMinimum;
31 
32  /// <summary>
33  /// Gets the short stop of ChandeKrollStop.
34  /// </summary>
36 
37  /// <summary>
38  /// Gets the long stop of ChandeKrollStop.
39  /// </summary>
41 
42  /// <summary>
43  /// Gets a flag indicating when this indicator is ready and fully initialized
44  /// </summary>
45  public override bool IsReady => Samples >= WarmUpPeriod;
46 
47  /// <summary>
48  /// Required period, in data points, for the indicator to be ready and fully initialized.
49  /// </summary>
50  public int WarmUpPeriod { get; }
51 
52  /// <summary>
53  /// Initializes a new instance of the <see cref="ChandeKrollStop"/> class.
54  /// </summary>
55  /// <param name="atrPeriod">The period over which to compute the average true range.</param>
56  /// <param name="atrMult">The ATR multiplier to be used to compute stops distance.</param>
57  /// <param name="period">The period over which to compute the max of high stop and min of low stop.</param>
58  /// <param name="movingAverageType">The type of smoothing used to smooth the true range values</param>
59  public ChandeKrollStop(int atrPeriod, decimal atrMult, int period, MovingAverageType movingAverageType = MovingAverageType.Wilders)
60  : this($"CKS({atrPeriod},{atrMult},{period})", atrPeriod, atrMult, period, movingAverageType)
61  {
62  }
63 
64  /// <summary>
65  /// Initializes a new instance of the <see cref="ChandeKrollStop"/> class.
66  /// </summary>
67  /// <param name="name">The name.</param>
68  /// <param name="atrPeriod">The period over which to compute the average true range.</param>
69  /// <param name="atrMult">The ATR multiplier to be used to compute stops distance.</param>
70  /// <param name="period">The period over which to compute the max of high stop and min of low stop.</param>
71  /// <param name="movingAverageType">The type of smoothing used to smooth the true range values</param>
72  public ChandeKrollStop(string name, int atrPeriod, decimal atrMult, int period, MovingAverageType movingAverageType = MovingAverageType.Wilders)
73  : base(name)
74  {
75  WarmUpPeriod = atrPeriod + period - 1;
76 
77  _atr = new AverageTrueRange(atrPeriod, movingAverageType);
78  _atrMult = atrMult;
79  _underlyingMaximum = new Maximum(atrPeriod);
80  _underlyingMinimum = new Minimum(atrPeriod);
81 
82  LongStop = new Minimum(name + "_Long", period);
83  ShortStop = new Maximum(name + "_Short", period);
84  }
85 
86  /// <summary>
87  /// Computes the next value of this indicator from the given state
88  /// </summary>
89  /// <param name="input">The input given to the indicator</param>
90  /// <returns>The input is returned unmodified.</returns>
91  protected override decimal ComputeNextValue(IBaseDataBar input)
92  {
93  _atr.Update(input);
94 
95  _underlyingMaximum.Update(input.EndTime, input.High);
96  var highStop = _underlyingMaximum.Current.Value - _atr.Current.Value * _atrMult;
97 
98  _underlyingMinimum.Update(input.EndTime, input.Low);
99  var lowStop = _underlyingMinimum.Current.Value + _atr.Current.Value * _atrMult;
100 
101  ShortStop.Update(input.EndTime, highStop);
102  LongStop.Update(input.EndTime, lowStop);
103 
104  return input.Value;
105  }
106 
107  /// <summary>
108  /// Resets this indicator to its initial state
109  /// </summary>
110  public override void Reset()
111  {
112  base.Reset();
113  _atr.Reset();
114  _underlyingMaximum.Reset();
115  _underlyingMinimum.Reset();
116  ShortStop.Reset();
117  LongStop.Reset();
118  }
119  }
120 }