Lean  $LEAN_TAG$
ValueAtRisk.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 MathNet.Numerics.Statistics;
17 using MathNet.Numerics.Distributions;
18 using System;
19 
21 {
22  /// <summary>
23  /// This indicator computes 1-day VaR for a specified confidence level and lookback period
24  /// </summary>
25  public class ValueAtRisk : WindowIndicator<IndicatorDataPoint>, IIndicatorWarmUpPeriodProvider
26  {
27  /// <summary>
28  /// Confidence level for VaR calculation
29  /// </summary>
30  private readonly double _confidenceLevel;
31 
32  /// <summary>
33  /// RateOfChange indicator to calculate the returns
34  /// </summary>
35  private readonly RateOfChange _rateOfChange;
36 
37  /// <summary>
38  /// Rolling window to store the returns of the input data
39  /// </summary>
40  private readonly RollingWindow<double> _returns;
41 
42  /// <summary>
43  /// Required period, in data points, for the indicator to be ready and fully initialized.
44  /// </summary>
45  public override int WarmUpPeriod { get; }
46 
47  /// <summary>
48  /// Gets a flag indicating when the indicator is ready and fully initialized
49  /// </summary>
50  public override bool IsReady => Samples >= WarmUpPeriod;
51 
52  /// <summary>
53  /// Creates a new ValueAtRisk indicator with a specified period and confidence level
54  /// </summary>
55  /// <param name="name">The name of this indicator</param>
56  /// <param name="period">Historical lookback period in days</param>
57  /// <param name="confidenceLevel">Confidence level for VaR calculation</param>
58  public ValueAtRisk(string name, int period, double confidenceLevel)
59  : base(name, period)
60  {
61  if (period < 3)
62  {
63  throw new ArgumentException($"Period parameter for ValueAtRisk indicator must be greater than 2 but was {period}");
64  }
65 
66  WarmUpPeriod = period;
67  _confidenceLevel = confidenceLevel;
68 
69  _returns = new RollingWindow<double>(period);
70  _rateOfChange = new RateOfChange(1);
71  }
72 
73  /// <summary>
74  /// Creates a new ValueAtRisk indicator with a specified period and confidence level
75  /// </summary>
76  /// <param name="period">Historical lookback period in days</param>
77  /// <param name="confidenceLevel">Confidence level for VaR calculation</param>
78  public ValueAtRisk(int period, double confidenceLevel)
79  : this($"VaR({period}, {confidenceLevel})", period, confidenceLevel)
80  {
81  }
82 
83  /// <summary>
84  /// Computes the next value for this indicator from the given state.
85  /// </summary>
86  /// <param name="window">The window of data held in this indicator</param>
87  /// <param name="input">The input value to this indicator on this time step</param>
88  /// <returns>A new value for this indicator</returns>
90  {
91  _rateOfChange.Update(input);
92  _returns.Add((double)_rateOfChange.Current.Value);
93 
94  if (_returns.Count < 2)
95  {
96  return 0m;
97  }
98 
99  var mean = _returns.Mean();
100  var standardDeviation = _returns.StandardDeviation();
101  return (decimal)Normal.InvCDF(mean, standardDeviation, 1 - _confidenceLevel);
102  }
103 
104  /// <summary>
105  /// Resets this indicator to its initial state
106  /// </summary>
107  public override void Reset()
108  {
109  _rateOfChange.Reset();
110  _returns.Reset();
111  base.Reset();
112  }
113  }
114 }
115