Lean
$LEAN_TAG$
Maximum.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.Linq;
17
18
namespace
QuantConnect.Indicators
19
{
20
/// <summary>
21
/// Represents an indicator capable of tracking the maximum value and how many periods ago it occurred
22
/// </summary>
23
public
class
Maximum
:
WindowIndicator
<IndicatorDataPoint>,
IIndicatorWarmUpPeriodProvider
24
{
25
/// <summary>
26
/// The number of periods since the maximum value was encountered
27
/// </summary>
28
public
int
PeriodsSinceMaximum
{
get
;
private
set
; }
29
30
/// <summary>
31
/// Gets a flag indicating when this indicator is ready and fully initialized
32
/// </summary>
33
public
override
bool
IsReady
=> Samples >=
Period
;
34
35
/// <summary>
36
/// Required period, in data points, for the indicator to be ready and fully initialized.
37
/// </summary>
38
public
int
WarmUpPeriod
=>
Period
;
39
40
/// <summary>
41
/// Creates a new Maximum indicator with the specified period
42
/// </summary>
43
/// <param name="period">The period over which to look back</param>
44
public
Maximum
(
int
period)
45
: base($
"MAX({period})"
, period)
46
{
47
}
48
49
/// <summary>
50
/// Creates a new Maximum indicator with the specified period
51
/// </summary>
52
/// <param name="name">The name of this indicator</param>
53
/// <param name="period">The period over which to look back</param>
54
public
Maximum
(
string
name,
int
period)
55
: base(name, period)
56
{
57
}
58
59
/// <inheritdoc />
60
protected
override
decimal
ComputeNextValue
(
IReadOnlyWindow<IndicatorDataPoint>
window,
IndicatorDataPoint
input)
61
{
62
if
(Samples == 1 || input.
Value
>= Current.Value)
63
{
64
// our first sample or if we're bigger than our previous indicator value
65
// reset the periods since maximum (it's this period) and return the value
66
PeriodsSinceMaximum
= 0;
67
return
input.
Value
;
68
}
69
70
if
(
PeriodsSinceMaximum
>=
Period
- 1)
71
{
72
// at this point we need to find a new maximum
73
// the window enumerates from most recent to oldest
74
// so let's scour the window for the max and it's index
75
76
// this could be done more efficiently if we were to intelligently keep track of the 'next'
77
// maximum, so when one falls off, we have the other... but then we would also need the 'next, next'
78
// maximum, so on and so forth, for now this works.
79
80
var maximum = window.Select((v, i) =>
new
81
{
82
Value = v,
83
Index = i
84
}).OrderByDescending(x => x.Value.Value).First();
85
86
PeriodsSinceMaximum
= maximum.Index;
87
return
maximum.Value.Value;
88
}
89
90
// if we made it here then we didn't see a new maximum and we haven't reached our period limit,
91
// so just increment our periods since maximum and return the same value as we had before
92
PeriodsSinceMaximum
++;
93
return
Current.Value;
94
}
95
96
/// <summary>
97
/// Resets this indicator to its initial state
98
/// </summary>
99
public
override
void
Reset
()
100
{
101
PeriodsSinceMaximum
= 0;
102
base.Reset();
103
}
104
}
105
}
Indicators
Maximum.cs
Generated by
1.8.17