Lean  $LEAN_TAG$
EaseOfMovementValue.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 */
16 
18 {
19  /// <summary>
20  /// This indicator computes the n-period Ease of Movement Value using the following:
21  /// MID = (high_1 + low_1)/2 - (high_0 + low_0)/2
22  /// RATIO = (currentVolume/10000) / (high_1 - low_1)
23  /// EMV = MID/RATIO
24  /// _SMA = n-period of EMV
25  /// Returns _SMA
26  /// Source: https://www.investopedia.com/terms/e/easeofmovement.asp
27  /// </summary>
29  {
30  private readonly SimpleMovingAverage _sma;
31  private readonly int _scale = 10000;
32  private decimal _previousHighMaximum;
33  private decimal _previousLowMinimum;
34 
35  /// <summary>
36  /// Gets a flag indicating when this indicator is ready and fully initialized
37  /// </summary>
38  public override bool IsReady => _sma.IsReady;
39 
40  /// <summary>
41  /// Required period, in data points, for the indicator to be ready and fully initialized.
42  /// </summary>
43  public int WarmUpPeriod => _sma.WarmUpPeriod;
44 
45  /// <summary>
46  /// Initializeds a new instance of the EaseOfMovement class using the specufued period
47  /// </summary>
48  /// <param name="period">The period over which to perform to computation</param>
49  /// <param name="scale">The size of the number outputed by EMV</param>
50  public EaseOfMovementValue(int period = 1, int scale = 10000)
51  : this($"EMV({period}, {scale})", period, scale)
52  {
53  }
54  /// <summary>
55  /// Creates a new EaseOfMovement indicator with the specified period
56  /// </summary>
57  /// <param name="name">The name of this indicator</param>
58  /// <param name="period">The period over which to perform to computation</param>
59  /// <param name="scale">The size of the number outputed by EMV</param>
60  public EaseOfMovementValue(string name, int period, int scale)
61  : base(name)
62  {
63  _sma = new SimpleMovingAverage(period);
64  _scale = scale;
65  }
66 
67  /// <summary>
68  /// Computes the next value for this indicator from the given state.
69  /// </summary>
70  /// <param name="input">The input value to this indicator on this time step</param>
71  /// <returns>A a value for this indicator</returns>
72  protected override decimal ComputeNextValue(TradeBar input)
73  {
74  if (_previousHighMaximum == 0 && _previousLowMinimum == 0)
75  {
76  _previousHighMaximum = input.High;
77  _previousLowMinimum = input.Low;
78  }
79 
80  if (input.Volume == 0 || input.High == input.Low)
81  {
82  _sma.Update(input.Time, 0);
83  return _sma.Current.Value;
84  }
85 
86  var midValue = ((input.High + input.Low) / 2) - ((_previousHighMaximum + _previousLowMinimum) / 2);
87  var midRatio = ((input.Volume / _scale) / (input.High - input.Low));
88 
89  _previousHighMaximum = input.High;
90  _previousLowMinimum = input.Low;
91 
92  _sma.Update(input.Time, midValue / midRatio);
93 
94  return _sma.Current.Value;
95  }
96 
97  /// <summary>
98  /// Resets this indicator to its initial state
99  /// </summary>
100  public override void Reset()
101  {
102  _sma.Reset();
103  _previousHighMaximum = 0.0m;
104  _previousLowMinimum = 0.0m;
105  base.Reset();
106  }
107  }
108 }