/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace QuantConnect.Indicators { /// /// This indicator computes the TRIX (1-period ROC of a Triple EMA) /// The TRIX is calculated as explained here: /// http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:trix /// public class Trix : Indicator, IIndicatorWarmUpPeriodProvider { private readonly int _period; private readonly ExponentialMovingAverage _ema1; private readonly ExponentialMovingAverage _ema2; private readonly ExponentialMovingAverage _ema3; private readonly RateOfChangePercent _roc; /// /// Initializes a new instance of the class using the specified name and period. /// /// The name of this indicator /// The period of the indicator public Trix(string name, int period) : base(name) { _period = period; _ema1 = new ExponentialMovingAverage(name + "_1", period); _ema2 = new ExponentialMovingAverage(name + "_2", period); _ema3 = new ExponentialMovingAverage(name + "_3", period); _roc = new RateOfChangePercent(name + "_ROCP1", 1); } /// /// Initializes a new instance of the class using the specified period. /// /// The period of the indicator public Trix(int period) : this($"TRIX({period})", period) { } /// /// Gets a flag indicating when this indicator is ready and fully initialized /// public override bool IsReady => _roc.IsReady; /// /// Required period, in data points, for the indicator to be ready and fully initialized. /// We have 3 EMAs chained on base period so every _period points starts the next EMA, /// hence -1 on the multiplication, and finally the last ema updates our _roc which needs /// to be warmed up before this indicator is warmed up. /// public int WarmUpPeriod => 3 * (_period - 1) + _roc.WarmUpPeriod; /// /// Computes the next value of this indicator from the given state /// /// The input given to the indicator /// A new value for this indicator protected override decimal ComputeNextValue(IndicatorDataPoint input) { _ema1.Update(input); if (_ema1.IsReady) _ema2.Update(_ema1.Current); if (_ema2.IsReady) _ema3.Update(_ema2.Current); if (_ema3.IsReady) _roc.Update(_ema3.Current); return _roc.Current.Value; } /// /// Resets this indicator to its initial state /// public override void Reset() { _ema1.Reset(); _ema2.Reset(); _ema3.Reset(); _roc.Reset(); base.Reset(); } } }