Lean  $LEAN_TAG$
AccelerationBands.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  /// The Acceleration Bands created by Price Headley plots upper and lower envelope bands around a moving average.
22  /// </summary>
23  /// <seealso cref="Indicators.IndicatorBase{IBaseDataBar}" />
25  {
26  private readonly decimal _width;
27 
28  /// <summary>
29  /// Gets the type of moving average
30  /// </summary>
32 
33  /// <summary>
34  /// Gets the middle acceleration band (moving average)
35  /// </summary>
37 
38  /// <summary>
39  /// Gets the upper acceleration band (High * ( 1 + Width * (High - Low) / (High + Low)))
40  /// </summary>
42 
43  /// <summary>
44  /// Gets the lower acceleration band (Low * (1 - Width * (High - Low)/ (High + Low)))
45  /// </summary>
47 
48  /// <summary>
49  /// Initializes a new instance of the <see cref="AccelerationBands" /> class.
50  /// </summary>
51  /// <param name="name">The name of this indicator.</param>
52  /// <param name="period">The period of the three moving average (middle, upper and lower band).</param>
53  /// <param name="width">A coefficient specifying the distance between the middle band and upper or lower bands.</param>
54  /// <param name="movingAverageType">Type of the moving average.</param>
55  public AccelerationBands(string name, int period, decimal width,
56  MovingAverageType movingAverageType = MovingAverageType.Simple)
57  : base(name)
58  {
59  WarmUpPeriod = period;
60  _width = width;
61  MovingAverageType = movingAverageType;
62  MiddleBand = movingAverageType.AsIndicator(name + "_MiddleBand", period);
63  LowerBand = movingAverageType.AsIndicator(name + "_LowerBand", period);
64  UpperBand = movingAverageType.AsIndicator(name + "_UpperBand", period);
65  }
66 
67  /// <summary>
68  /// Initializes a new instance of the <see cref="AccelerationBands" /> class.
69  /// </summary>
70  /// <param name="period">The period of the three moving average (middle, upper and lower band).</param>
71  /// <param name="width">A coefficient specifying the distance between the middle band and upper or lower bands.</param>
72  public AccelerationBands(int period, decimal width)
73  : this($"ABANDS({period},{width})", period, width)
74  {
75  }
76 
77  /// <summary>
78  /// Initializes a new instance of the <see cref="AccelerationBands" /> class.
79  /// </summary>
80  /// <param name="period">The period of the three moving average (middle, upper and lower band).</param>
81  public AccelerationBands(int period)
82  : this(period, 4)
83  {
84  }
85 
86  /// <summary>
87  /// Gets a flag indicating when this indicator is ready and fully initialized
88  /// </summary>
89  public override bool IsReady => MiddleBand.IsReady && LowerBand.IsReady && UpperBand.IsReady;
90 
91  /// <summary>
92  /// Required period, in data points, for the indicator to be ready and fully initialized.
93  /// </summary>
94  public int WarmUpPeriod { get; }
95 
96  /// <summary>
97  /// Resets this indicator to its initial state
98  /// </summary>
99  public override void Reset()
100  {
101  base.Reset();
102  MiddleBand.Reset();
103  LowerBand.Reset();
104  UpperBand.Reset();
105  }
106 
107  /// <summary>
108  /// Computes the next value of this indicator from the given state
109  /// </summary>
110  /// <param name="input">The input given to the indicator</param>
111  /// <returns>
112  /// A new value for this indicator
113  /// </returns>
114  protected override decimal ComputeNextValue(IBaseDataBar input)
115  {
116  var coefficient = _width * (input.High - input.Low).SafeDivision(input.High + input.Low);
117 
118  LowerBand.Update(input.Time, input.Low * (1 - coefficient));
119  UpperBand.Update(input.Time, input.High * (1 + coefficient));
120  MiddleBand.Update(input.Time, input.Close);
121 
122  return MiddleBand.Current.Value;
123  }
124  }
125 }