/// <inheritdoc />
        protected override decimal ComputeNextValue(IReadOnlyWindow <IndicatorDataPoint> window, IndicatorDataPoint input)
        {
            if (Samples == 1 || input.Value <= Current.Value)
            {
                // our first sample or if we're bigger than our previous indicator value
                // reset the periods since minimum (it's this period) and return the value
                PeriodsSinceMinimum = 0;
                return(input.Value);
            }

            if (PeriodsSinceMinimum >= Period - 1)
            {
                // at this point we need to find a new minimum
                // the window enumerates from most recent to oldest
                // so let's scour the window for the max and it's index

                // this could be done more efficiently if we were to intelligently keep track of the 'next'
                // minimum, so when one falls off, we have the other... but then we would also need the 'next, next'
                // minimum, so on and so forth, for now this works.

                var minimum = window.Select((v, i) => new
                {
                    Value = v,
                    Index = i
                }).OrderBy(x => x.Value.Value).First();

                PeriodsSinceMinimum = minimum.Index;
                return(minimum.Value);
            }

            // if we made it here then we didn't see a new minimum and we haven't reached our period limit,
            // so just increment our periods since minimum and return the same value as we had before
            PeriodsSinceMinimum++;
            return(Current);
        }
Exemple #2
0
 /// <summary>
 /// Computes the next value for this indicator from the given state.
 /// </summary>
 /// <param name="window">The window of data held in this indicator</param>
 /// <param name="input">The input value to this indicator on this time step</param>
 /// <returns>
 /// A new value for this indicator
 /// </returns>
 /// <exception cref="System.NotImplementedException"></exception>
 protected override decimal ComputeNextValue(IReadOnlyWindow <IndicatorDataPoint> window,
                                             IndicatorDataPoint input)
 {
     return(IsReady
         ? window.Select((t, i) => t.Price * _weightVector[i]).Sum()
         : input.Value);
 }
 /// <summary>
 ///      Computes the next value for this indicator from the given state.
 /// </summary>
 /// <param name="timeWindow"></param>
 /// <param name="window">The window of data held in this indicator</param>
 /// <param name="time"></param>
 /// <param name="input">The input value to this indicator on this time step</param>
 /// <returns>
 ///      A new value for this indicator
 /// </returns>
 /// <exception cref="System.NotImplementedException"></exception>
 protected override DoubleArray Forward(IReadOnlyWindow <long> timeWindow, IReadOnlyWindow <DoubleArray> window,
                                        long time,
                                        DoubleArray input)
 {
     return(IsReady
         ? window.Select((t, i) => t.Value * _weightVector[i]).Sum()
         : input);
 }
Exemple #4
0
        /// <summary>
        /// Computes the next value of this indicator from the given state
        /// </summary>
        /// <param name="input">The input given to the indicator</param>
        /// <returns>A new value for this indicator</returns>
        protected override decimal ComputeNextValue(IReadOnlyWindow <IndicatorDataPoint> window, IndicatorDataPoint input)
        {
            if (Samples < 2)
            {
                return(0m);
            }
            IEnumerable <double> doubleValues = window.Select(i => Convert.ToDouble(i.Value));
            double std = MathNetStatistics.PopulationStandardDeviation(doubleValues);

            return(Convert.ToDecimal(std));
        }