Lean
$LEAN_TAG$
BollingerBands.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
namespace
QuantConnect.Indicators
17
{
18
/// <summary>
19
/// This indicator creates a moving average (middle band) with an upper band and lower band
20
/// fixed at k standard deviations above and below the moving average.
21
/// </summary>
22
public
class
BollingerBands
:
Indicator
,
IIndicatorWarmUpPeriodProvider
23
{
24
/// <summary>
25
/// Gets the type of moving average
26
/// </summary>
27
public
MovingAverageType
MovingAverageType
{
get
; }
28
29
/// <summary>
30
/// Gets the standard deviation
31
/// </summary>
32
public
IndicatorBase<IndicatorDataPoint>
StandardDeviation
{
get
; }
33
34
/// <summary>
35
/// Gets the middle Bollinger band (moving average)
36
/// </summary>
37
public
IndicatorBase<IndicatorDataPoint>
MiddleBand
{
get
; }
38
39
/// <summary>
40
/// Gets the upper Bollinger band (middleBand + k * stdDev)
41
/// </summary>
42
public
IndicatorBase<IndicatorDataPoint>
UpperBand
{
get
; }
43
44
/// <summary>
45
/// Gets the lower Bollinger band (middleBand - k * stdDev)
46
/// </summary>
47
public
IndicatorBase<IndicatorDataPoint>
LowerBand
{
get
; }
48
49
/// <summary>
50
/// Gets the Bollinger BandWidth indicator
51
/// BandWidth = ((Upper Band - Lower Band) / Middle Band) * 100
52
/// </summary>
53
public
IndicatorBase<IndicatorDataPoint>
BandWidth
{
get
; }
54
55
/// <summary>
56
/// Gets the Bollinger %B
57
/// %B = (Price - Lower Band)/(Upper Band - Lower Band)
58
/// </summary>
59
public
IndicatorBase<IndicatorDataPoint>
PercentB
{
get
; }
60
61
/// <summary>
62
/// Gets the Price level
63
/// </summary>
64
public
IndicatorBase<IndicatorDataPoint>
Price
{
get
; }
65
66
/// <summary>
67
/// Initializes a new instance of the BollingerBands class
68
/// </summary>
69
/// <param name="period">The period of the standard deviation and moving average (middle band)</param>
70
/// <param name="k">The number of standard deviations specifying the distance between the middle band and upper or lower bands</param>
71
/// <param name="movingAverageType">The type of moving average to be used</param>
72
public
BollingerBands
(
int
period, decimal k,
MovingAverageType
movingAverageType =
MovingAverageType
.Simple)
73
: this($
"BB({period},{k})"
, period, k, movingAverageType)
74
{
75
}
76
77
/// <summary>
78
/// Initializes a new instance of the BollingerBands class
79
/// </summary>
80
/// <param name="name">The name of this indicator</param>
81
/// <param name="period">The period of the standard deviation and moving average (middle band)</param>
82
/// <param name="k">The number of standard deviations specifying the distance between the middle band and upper or lower bands</param>
83
/// <param name="movingAverageType">The type of moving average to be used</param>
84
public
BollingerBands
(
string
name,
int
period, decimal k,
MovingAverageType
movingAverageType =
MovingAverageType
.Simple)
85
: base(name)
86
{
87
WarmUpPeriod
= period;
88
MovingAverageType
= movingAverageType;
89
StandardDeviation
=
new
StandardDeviation
(name +
"_StandardDeviation"
, period);
90
MiddleBand
= movingAverageType.AsIndicator(name +
"_MiddleBand"
, period);
91
LowerBand
=
MiddleBand
.Minus(
StandardDeviation
.Times(k), name +
"_LowerBand"
);
92
UpperBand
=
MiddleBand
.Plus(
StandardDeviation
.Times(k), name +
"_UpperBand"
);
93
94
var UpperMinusLower =
UpperBand
.Minus(
LowerBand
);
95
BandWidth
= UpperMinusLower
96
.Over(
MiddleBand
)
97
.Times(
new
ConstantIndicator<IndicatorDataPoint>
(
"ct"
, 100m), name +
"_BandWidth"
);
98
99
Price
=
new
Identity
(name +
"_Close"
);
100
PercentB
=
IndicatorExtensions
.
Over
(
101
Price
.Minus(
LowerBand
),
102
UpperMinusLower,
103
name +
"_%B"
);
104
}
105
106
/// <summary>
107
/// Gets a flag indicating when this indicator is ready and fully initialized
108
/// </summary>
109
public
override
bool
IsReady
=>
MiddleBand
.IsReady &&
UpperBand
.IsReady &&
LowerBand
.IsReady &&
BandWidth
.IsReady &&
PercentB
.IsReady;
110
111
/// <summary>
112
/// Required period, in data points, for the indicator to be ready and fully initialized.
113
/// </summary>
114
public
int
WarmUpPeriod
{
get
; }
115
116
/// <summary>
117
/// Computes the next value of the following sub-indicators from the given state:
118
/// StandardDeviation, MiddleBand, UpperBand, LowerBand, BandWidth, %B
119
/// </summary>
120
/// <param name="input">The input given to the indicator</param>
121
/// <returns>The input is returned unmodified.</returns>
122
protected
override
decimal
ComputeNextValue
(
IndicatorDataPoint
input)
123
{
124
StandardDeviation
.Update(input);
125
MiddleBand
.Update(input);
126
Price
.Update(input);
127
128
return
input.
Value
;
129
}
130
131
/// <summary>
132
/// Validate and Compute the next value for this indicator
133
/// </summary>
134
/// <param name="input">Input for this indicator</param>
135
/// <returns><see cref="IndicatorResult"/> of this update</returns>
136
/// <remarks>Override implemented to handle GH issue #4927</remarks>
137
protected
override
IndicatorResult
ValidateAndComputeNextValue
(
IndicatorDataPoint
input)
138
{
139
// Update our Indicators
140
var value =
ComputeNextValue
(input);
141
142
// If the STD = 0, we know that the our PercentB indicator will fail to update. This is
143
// because the denominator will be 0. When this is the case after fully ready we do not
144
// want the BollingerBands to emit an update because its PercentB property will be stale.
145
return
IsReady
&&
StandardDeviation
.Current.Value == 0
146
?
new
IndicatorResult
(value,
IndicatorStatus
.MathError)
147
:
new
IndicatorResult
(value);
148
}
149
150
/// <summary>
151
/// Resets this indicator and all sub-indicators (StandardDeviation, LowerBand, MiddleBand, UpperBand, BandWidth, %B)
152
/// </summary>
153
public
override
void
Reset
()
154
{
155
StandardDeviation
.
Reset
();
156
MiddleBand
.Reset();
157
UpperBand
.Reset();
158
LowerBand
.Reset();
159
BandWidth
.Reset();
160
PercentB
.Reset();
161
base.Reset();
162
}
163
}
164
}
Indicators
BollingerBands.cs
Generated by
1.8.17