Lean  $LEAN_TAG$
ChaikinMoneyFlow.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 Chaikin Money Flow Index (CMF) is a volume-weighted average of accumulation and distribution over
22  /// a specified period.
23  ///
24  /// CMF = n-day Sum of [(((C - L) - (H - C)) / (H - L)) x Vol] / n-day Sum of Vol
25  ///
26  /// Where:
27  /// n = number of periods, typically 21
28  /// H = high
29  /// L = low
30  /// C = close
31  /// Vol = volume
32  ///
33  /// https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/cmf
34  /// </summary>
36  {
37  /// <summary>
38  /// Holds the point-wise flow-sum and volume terms.
39  /// </summary>
40  private readonly Sum _flowRatioSum;
41 
42  private readonly Sum _volumeSum;
43 
44  /// <summary>
45  /// Gets a flag indicating when this indicator is ready and fully initialized
46  /// </summary>
47  public override bool IsReady => _flowRatioSum.IsReady;
48 
49  /// <summary>
50  /// Required period, in data points, for the indicator to be ready and fully initialized.
51  /// </summary>
52  public int WarmUpPeriod { get; }
53 
54  /// <summary>
55  /// Resets this indicator to its initial state
56  /// </summary>
57  public override void Reset()
58  {
59  _volumeSum.Reset();
60  _flowRatioSum.Reset();
61  base.Reset();
62  }
63 
64  /// <summary>
65  /// Initializes a new instance of the ChaikinMoneyFlow class
66  /// </summary>
67  /// <param name="name">A name for the indicator</param>
68  /// <param name="period">The period over which to perform computation</param>
69  public ChaikinMoneyFlow(string name, int period)
70  : base($"CMF({name})")
71  {
72  WarmUpPeriod = period;
73  _flowRatioSum = new Sum(period);
74  _volumeSum = new Sum(period);
75  }
76 
77  /// <summary>
78  /// Computes the next value for this indicator from the given state.
79  /// </summary>
80  /// <param name="input">The input value to this indicator on this time step</param>
81  /// <returns>A new value for this indicator</returns>
82  protected override decimal ComputeNextValue(TradeBar input)
83  {
84  var denominator = (input.High - input.Low);
85  var flowRatio = denominator > 0
86  ? input.Volume * (input.Close - input.Low - (input.High - input.Close)) / denominator
87  : 0m;
88 
89  _flowRatioSum.Update(input.EndTime, flowRatio);
90  _volumeSum.Update(input.EndTime, input.Volume);
91 
92  return !IsReady || _volumeSum == 0m ? 0m : _flowRatioSum / _volumeSum;
93  }
94  }
95 }