Example #1
0
 public InflectionPoint(SignalDataByTime signalValue, int indexOrigin, ExtremaType extremum)
 {
     this.x            = signalValue.Time;
     this.y            = signalValue.SignalValue;
     this.index        = indexOrigin;
     this.extremumType = extremum;
 }
Example #2
0
 public InflectionPoint(EDASignal signalValue, int indexOrigin, ExtremaType extremum)
 {
     this.x            = signalValue.time;
     this.y            = signalValue.value;
     this.index        = indexOrigin;
     this.extremumType = extremum;
 }
Example #3
0
        public static void Print(this IEnumerable <ExtremaGroup> extremaGroups, ExtremaType extremaType)
        {
            var list = extremaType == ExtremaType.Minimum
                ? extremaGroups.OrderByDescending(c => c.Average)
                : extremaGroups.OrderBy(c => c.Average);

            foreach (var extremaGroup in list)
            {
                extremaGroup.Print();
            }
        }
        public List <ExtremaGroup> GetSupportExtremaGroups(List <Price> prices, ExtremaType extremePoint, double offsetPercent)
        {
            // Get extrema points
            var extremePoints = GetExtremePoints(prices, extremePoint, offsetPercent);

            // Filter broken limits
            extremePoints = FilterBrokenLimits(extremePoints, ExtremaType.Minimum, offsetPercent);

            // Merge group
            var extremaGroups = MergeGroups(extremePoints, 1);

            return(extremaGroups);
        }
        private static List <Extrema> GetExtremePoints(List <Price> prices, ExtremaType extremePoint, double offsetPercent)
        {
            var potentials = new List <Price>();

            for (var i = 0; i < prices.Count - 1; i++)
            {
                if (i == 0)
                {
                    continue;
                }

                var yesterday = prices[i - 1].Close;
                var today     = prices[i].Close;
                var tomorrow  = prices[i + 1].Close;

                switch (extremePoint)
                {
                case ExtremaType.Minimum:
                    if (today.IsMinima(yesterday, tomorrow))
                    {
                        potentials.Add(prices[i]);
                    }
                    break;

                case ExtremaType.Maximum:
                    if (today.IsMaxima(yesterday, tomorrow))
                    {
                        potentials.Add(prices[i]);
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(extremePoint), extremePoint, null);
                }
            }

            var extremePoints = potentials.Select(p => new Extrema(p, offsetPercent)).ToList();

            return(extremePoints);
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="index">Data index of extrema.</param>
 /// <param name="extremaType">The type of extrema (maxima or minima).</param>
 public ExtremaPoint(int index, ExtremaType extremaType)
 {
     this.index       = index;
     this.extremaType = extremaType;
 }
        /// <summary>
        /// Looking for inflection points in a list of signal values.
        /// If we have a sequence of more than two signal values with the same value (points are collinear)
        /// we take for inflection points only the first and last.
        /// </summary>
        ///
        /// <param name="signalCoordinatePoints"> List of signal values. </param>
        ///
        /// <returns>
        /// List of founded inflection points.
        /// </returns>
        public List <InflectionPoint> GetInflectionPoints(List <SignalDataByTime> signalCoordinatePoints, string dataType)
        {
            List <InflectionPoint> inflectionPoints = new List <InflectionPoint>();
            int candidateInflectionPoint            = -1;

            //add the first and the last signal value
            double firstInflectionPoints  = (("default").Equals(dataType)) ? signalCoordinatePoints[0].SignalValue : (("highPass").Equals(dataType)) ? signalCoordinatePoints[0].HighPassValue : signalCoordinatePoints[0].LowPassValue;
            double secondInflectionPoints = (("default").Equals(dataType)) ? signalCoordinatePoints[1].SignalValue : (("highPass").Equals(dataType)) ? signalCoordinatePoints[1].HighPassValue : signalCoordinatePoints[1].LowPassValue;

            inflectionPoints.Add(new InflectionPoint(signalCoordinatePoints[0], 0, GetExtremaType(null, firstInflectionPoints, secondInflectionPoints)));
            double penultimateInflectionPoint = (("default").Equals(dataType)) ? signalCoordinatePoints[signalCoordinatePoints.Count - 2].SignalValue : (("highPass").Equals(dataType)) ? signalCoordinatePoints[signalCoordinatePoints.Count - 2].HighPassValue : signalCoordinatePoints[signalCoordinatePoints.Count - 2].LowPassValue;
            double lastInflectionPoint        = (("default").Equals(dataType)) ? signalCoordinatePoints[signalCoordinatePoints.Count - 1].SignalValue : (("highPass").Equals(dataType)) ? signalCoordinatePoints[signalCoordinatePoints.Count - 1].HighPassValue : signalCoordinatePoints[signalCoordinatePoints.Count - 1].LowPassValue;

            inflectionPoints.Add(new InflectionPoint(signalCoordinatePoints[signalCoordinatePoints.Count - 1], signalCoordinatePoints.Count - 1, GetExtremaType(penultimateInflectionPoint, lastInflectionPoint, null)));

            double currentFindLastInflectionPoint = firstInflectionPoints;

            for (int i = 1; i < (signalCoordinatePoints.Count - 1); i++)
            {
                double      currentPointY  = (("default").Equals(dataType)) ? signalCoordinatePoints[i].SignalValue : (("highPass").Equals(dataType)) ? signalCoordinatePoints[i].HighPassValue : signalCoordinatePoints[i].LowPassValue;
                double      previousPointY = (("default").Equals(dataType)) ? signalCoordinatePoints[i - 1].SignalValue : (("highPass").Equals(dataType)) ? signalCoordinatePoints[i - 1].HighPassValue : signalCoordinatePoints[i - 1].LowPassValue;
                double      nextPointY     = (("default").Equals(dataType)) ? signalCoordinatePoints[i + 1].SignalValue : (("highPass").Equals(dataType)) ? signalCoordinatePoints[i + 1].HighPassValue : signalCoordinatePoints[i + 1].LowPassValue;
                ExtremaType extremumType   = GetExtremaType(previousPointY, currentPointY, nextPointY);

                if (!extremumType.Equals(ExtremaType.None))
                {
                    if (currentPointY.CompareTo(currentFindLastInflectionPoint) != 0)
                    {
                        if (i > 0 && inflectionPoints.Count > 0)
                        {
                            if ((candidateInflectionPoint + 1) == i &&
                                inflectionPoints[inflectionPoints.Count - 1].CoordinateY.Equals(currentFindLastInflectionPoint))
                            {
                                inflectionPoints.Add(new InflectionPoint(signalCoordinatePoints[candidateInflectionPoint], candidateInflectionPoint, extremumType));
                            }
                        }

                        inflectionPoints.Add(new InflectionPoint(signalCoordinatePoints[i], i, extremumType));
                    }
                    else
                    {
                        candidateInflectionPoint = i;
                    }

                    currentFindLastInflectionPoint = currentPointY;
                }

                /*else
                 * {
                 *  if (i > 0 && inflectionPoints.Count > 0)
                 *  {
                 *      if ((candidateInflectionPoint + 1) == i && inflectionPoints[inflectionPoints.Count - 1].CoordinateY.Equals(signalCoordinatePoints[i - 1].SignalValue))
                 *      {
                 *          inflectionPoints.Add(new InflectionPoint(signalCoordinatePoints[candidateInflectionPoint], candidateInflectionPoint, extremumType));
                 *      }
                 *  }
                 * }*/
            }

            return(inflectionPoints);
        }
        private static bool IsInOffsetRange(double offsetPercent, float currentValue, float extremaValue, ExtremaType extremaType)
        {
            switch (extremaType)
            {
            case ExtremaType.Minimum:
                return(currentValue < (extremaValue + (extremaValue * offsetPercent) / 100));

            case ExtremaType.Maximum:
                return(currentValue > (extremaValue - (extremaValue + offsetPercent) / 100));

            default:
                throw new ArgumentOutOfRangeException(nameof(extremaType), extremaType, null);
            }
        }
        private static List <Extrema> FilterBrokenLimits(List <Extrema> extremePoints, ExtremaType extremaType, double offsetPercent)
        {
            extremePoints.Reverse();

            var mostExtrema = extremaType == ExtremaType.Minimum ? float.MaxValue : float.MinValue;

            var activePoints = new List <Extrema>();

            foreach (var point in extremePoints)
            {
                var val = point.CurrentPrice.Close;

                if (!activePoints.Any())
                {
                    activePoints.Add(point);
                    mostExtrema = val;
                }
                else
                {
                    var shouldCheckOffset = false;

                    switch (extremaType)
                    {
                    case ExtremaType.Minimum:
                    {
                        // Even if bigger, check if is in offset
                        if (mostExtrema < val)
                        {
                            shouldCheckOffset = true;
                        }
                        break;
                    }

                    case ExtremaType.Maximum:
                    {
                        // Even if smaller, check if is in offset
                        if (mostExtrema > val)
                        {
                            shouldCheckOffset = true;
                        }
                        break;
                    }

                    default:
                        throw new ArgumentOutOfRangeException(nameof(extremaType), extremaType, null);
                    }

                    if (shouldCheckOffset)
                    {
                        if (IsInOffsetRange(offsetPercent, val, mostExtrema, extremaType))
                        {
                            activePoints.Add(point);
                        }
                        continue;
                    }

                    mostExtrema = val;
                    activePoints.Add(point);
                }
            }

            return(activePoints);
        }