/* * 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. */ using System.Collections.Generic; using System.Linq; namespace QuantConnect.Indicators { /// /// The base class for any Time Series-type indicator, containing methods common to most of such models. /// public abstract class TimeSeriesIndicator : IndicatorBase, IIndicatorWarmUpPeriodProvider { /// /// "Integration" constants /// protected double[] _diffHeads { get; set; } /// /// Required period, in data points, for the indicator to be ready and fully initialized. /// public abstract int WarmUpPeriod { get; } /// /// A constructor for a basic Time Series indicator. /// /// The name of this indicator protected TimeSeriesIndicator(string name) : base(name) { } /// /// Differences a time series d times. /// /// Series to difference /// The differencing order /// "Integration" constants public static double[] DifferenceSeries(int d, double[] series, out double[] diffHeads) { diffHeads = new double[d]; if (d == 0) { return null; } var localSeries = series; for (var j = 1; j <= d; j++) { var result = new double[localSeries.Length - 1]; diffHeads[j - 1] = localSeries.Last(); for (var i = 0; i <= localSeries.Length - 2; i++) { result[i] = localSeries[i] - localSeries[i + 1]; } localSeries = result; } return localSeries; } /// /// Undoes the differencing of a time series which has been differenced using . /// https://github.com/statsmodels/statsmodels/blob/04f00006a7aeb1c93d6894caa420698400da6c33/statsmodels/tsa/tsatools.py#L758 /// /// Series to un-difference /// Series of "integration" constants for un-differencing public static double[] InverseDifferencedSeries(double[] series, double[] diffHeads) { var localDiffs = new Stack(diffHeads.Reverse()); var localSeries = series.ToList(); while (localDiffs.Count > 0) { var first = localDiffs.Pop(); localSeries.Add(first); localSeries = CumulativeSum(localSeries, true); } return localSeries.ToArray(); } /// /// Returns an array of lagged series for each of {1,...,p} lags. /// /// Max lag order /// Series to calculate the lags of /// Whether or not to include t with its lags in the output array /// A list such that index i returns the series for i+1 lags public static double[][] LaggedSeries(int p, double[] series, bool includeT = false) { // P-defined lagging - for each X_t, return double[] of the relevant lagged terms var toArray = new List(); for (var t = p; t < series.Length; t++) { var localLag = new List(); for (var j = includeT ? 0 : 1; j <= p; j++) { localLag.Add(series[t - j]); } toArray.Add(localLag.ToArray()); } return toArray.ToArray(); } /// /// Returns a series where each spot is taken by the cumulative sum of all points up to and including /// the value at that spot in the original series. /// /// Series to cumulatively sum over. /// Whether to reverse the series before applying the cumulative sum. /// Cumulatively summed series. public static List CumulativeSum(List series, bool reverse = false) { var localSeries = series; if (reverse) { localSeries.Reverse(); // For top-down } var sums = 0d; var outSeries = new List(); foreach (var val in localSeries) { sums += val; outSeries.Add(sums); } if (reverse) { outSeries.Reverse(); // Return to original order } return outSeries; } } }