Esempio n. 1
0
        private static ZigZagEval GetZigZagEval <TQuote>(ZigZagType type, int index, TQuote q) where TQuote : IQuote
        {
            ZigZagEval eval = new ZigZagEval()
            {
                Index = index
            };

            // consider `type`
            switch (type)
            {
            case ZigZagType.Close:

                eval.Low  = q.Close;
                eval.High = q.Close;
                break;

            case ZigZagType.HighLow:

                eval.Low  = q.Low;
                eval.High = q.High;
                break;
            }

            return(eval);
        }
Esempio n. 2
0
        private static ZigZagEval GetZigZagEval(ZigZagType type, Quote q)
        {
            ZigZagEval eval = new ZigZagEval()
            {
                Index = (int)q.Index
            };

            // consider `type`
            switch (type)
            {
            case ZigZagType.Close:

                eval.Low  = q.Close;
                eval.High = q.Close;
                break;

            case ZigZagType.HighLow:

                eval.Low  = q.Low;
                eval.High = q.High;
                break;
            }

            return(eval);
        }
Esempio n. 3
0
        // ZIG ZAG
        public static IEnumerable <ZigZagResult> GetZigZag <TQuote>(
            IEnumerable <TQuote> history,
            ZigZagType type       = ZigZagType.Close,
            decimal percentChange = 5)
            where TQuote : IQuote
        {
            // clean quotes
            List <TQuote> historyList = history.Sort();

            // check parameters
            ValidateZigZag(history, percentChange);

            // initialize
            List <ZigZagResult> results         = new List <ZigZagResult>(historyList.Count);
            decimal             changeThreshold = percentChange / 100m;
            TQuote     firstQuote = historyList[0];
            ZigZagEval eval       = GetZigZagEval(type, 1, firstQuote);

            ZigZagPoint lastPoint = new ZigZagPoint
            {
                Index     = eval.Index,
                Value     = firstQuote.Close,
                PointType = "U"
            };

            ZigZagPoint lastHighPoint = new ZigZagPoint
            {
                Index     = eval.Index,
                Value     = eval.High,
                PointType = "H"
            };

            ZigZagPoint lastLowPoint = new ZigZagPoint
            {
                Index     = eval.Index,
                Value     = eval.Low,
                PointType = "L"
            };

            int finalPointIndex = historyList.Count;

            // roll through history until to find initial trend
            for (int i = 0; i < historyList.Count; i++)
            {
                TQuote h     = historyList[i];
                int    index = i + 1;

                eval = GetZigZagEval(type, index, h);
                decimal changeUp = (eval.High - lastLowPoint.Value) / lastLowPoint.Value;
                decimal changeDn = (lastHighPoint.Value - eval.Low) / lastHighPoint.Value;

                if (changeUp >= changeThreshold && changeUp > changeDn)
                {
                    lastPoint.Index     = lastLowPoint.Index;
                    lastPoint.Value     = lastLowPoint.Value;
                    lastPoint.PointType = lastLowPoint.PointType;
                    break;
                }

                if (changeDn >= changeThreshold && changeDn > changeUp)
                {
                    lastPoint.Index     = lastHighPoint.Index;
                    lastPoint.Value     = lastHighPoint.Value;
                    lastPoint.PointType = lastHighPoint.PointType;
                    break;
                }
            }

            // add first point to results
            ZigZagResult firstResult = new ZigZagResult
            {
                Date = firstQuote.Date
            };

            results.Add(firstResult);

            // find and draw lines
            while (lastPoint.Index < finalPointIndex)
            {
                ZigZagPoint nextPoint     = EvaluateNextPoint(historyList, type, changeThreshold, lastPoint);
                string      lastDirection = lastPoint.PointType;

                // draw line (and reset last point)
                DrawZigZagLine(results, historyList, lastPoint, nextPoint);

                // draw retrace line (and reset last high/low point)
                DrawRetraceLine(results, lastDirection, lastLowPoint, lastHighPoint, nextPoint);
            }

            return(results);
        }
Esempio n. 4
0
        private static ZigZagPoint EvaluateNextPoint <TQuote>(List <TQuote> historyList,
                                                              ZigZagType type, decimal changeThreshold, ZigZagPoint lastPoint) where TQuote : IQuote
        {
            // initialize
            bool    trendUp = (lastPoint.PointType == "L");
            decimal?change  = 0;

            ZigZagPoint extremePoint = new ZigZagPoint
            {
                Index     = lastPoint.Index,
                Value     = lastPoint.Value,
                PointType = trendUp ? "H" : "L"
            };

            // find extreme point before reversal point
            for (int i = lastPoint.Index; i < historyList.Count; i++)
            {
                TQuote h     = historyList[i];
                int    index = i + 1;

                ZigZagEval eval = GetZigZagEval(type, index, h);

                // reset extreme point
                switch (trendUp)
                {
                case true:

                    if (eval.High >= extremePoint.Value)
                    {
                        extremePoint.Index = eval.Index;
                        extremePoint.Value = eval.High;
                    }
                    else
                    {
                        change = (extremePoint.Value == 0) ? null
                                : (extremePoint.Value - eval.Low) / extremePoint.Value;
                    }

                    break;

                case false:

                    if (eval.Low <= extremePoint.Value)
                    {
                        extremePoint.Index = eval.Index;
                        extremePoint.Value = eval.Low;
                    }
                    else
                    {
                        change = (extremePoint.Value == 0) ? null
                                : (eval.High - extremePoint.Value) / extremePoint.Value;
                    }

                    break;
                }

                // return extreme point when deviation threshold met
                if (change >= changeThreshold)
                {
                    return(extremePoint);
                }
            }

            // handle last unconfirmed point
            int finalPointIndex = historyList.Count;

            if (extremePoint.Index == finalPointIndex && change < changeThreshold)
            {
                extremePoint.PointType = null;
            }

            return(extremePoint);
        }
Esempio n. 5
0
        // ZIG ZAG
        /// <include file='./info.xml' path='indicator/*' />
        ///
        public static IEnumerable <ZigZagResult> GetZigZag <TQuote>(
            IEnumerable <TQuote> history,
            ZigZagType type       = ZigZagType.Close,
            decimal percentChange = 5)
            where TQuote : IQuote
        {
            // sort history
            List <TQuote> historyList = history.Sort();

            // check parameter arguments
            ValidateZigZag(history, percentChange);

            // initialize
            List <ZigZagResult> results         = new(historyList.Count);
            decimal             changeThreshold = percentChange / 100m;
            TQuote     firstQuote = historyList[0];
            ZigZagEval eval       = GetZigZagEval(type, 1, firstQuote);

            ZigZagPoint lastPoint = new()
            {
                Index     = eval.Index,
                Value     = firstQuote.Close,
                PointType = "U"
            };

            ZigZagPoint lastHighPoint = new()
            {
                Index     = eval.Index,
                Value     = eval.High,
                PointType = "H"
            };

            ZigZagPoint lastLowPoint = new()
            {
                Index     = eval.Index,
                Value     = eval.Low,
                PointType = "L"
            };

            int finalPointIndex = historyList.Count;

            // roll through history, to find initial trend
            for (int i = 0; i < historyList.Count; i++)
            {
                TQuote h     = historyList[i];
                int    index = i + 1;

                eval = GetZigZagEval(type, index, h);

                decimal?changeUp = (lastLowPoint.Value == 0) ? null
                    : (eval.High - lastLowPoint.Value) / lastLowPoint.Value;

                decimal?changeDn = (lastHighPoint.Value == 0) ? null
                    : (lastHighPoint.Value - eval.Low) / lastHighPoint.Value;

                if (changeUp >= changeThreshold && changeUp > changeDn)
                {
                    lastPoint.Index     = lastLowPoint.Index;
                    lastPoint.Value     = lastLowPoint.Value;
                    lastPoint.PointType = lastLowPoint.PointType;
                    break;
                }

                if (changeDn >= changeThreshold && changeDn > changeUp)
                {
                    lastPoint.Index     = lastHighPoint.Index;
                    lastPoint.Value     = lastHighPoint.Value;
                    lastPoint.PointType = lastHighPoint.PointType;
                    break;
                }
            }

            // add first point to results
            ZigZagResult firstResult = new()
            {
                Date = firstQuote.Date
            };

            results.Add(firstResult);

            // find and draw lines
            while (lastPoint.Index < finalPointIndex)
            {
                ZigZagPoint nextPoint     = EvaluateNextPoint(historyList, type, changeThreshold, lastPoint);
                string      lastDirection = lastPoint.PointType;

                // draw line (and reset last point)
                DrawZigZagLine(results, historyList, lastPoint, nextPoint);

                // draw retrace line (and reset last high/low point)
                DrawRetraceLine(results, lastDirection, lastLowPoint, lastHighPoint, nextPoint);
            }

            return(results);
        }

        private static ZigZagPoint EvaluateNextPoint <TQuote>(
            List <TQuote> historyList,
            ZigZagType type, decimal changeThreshold, ZigZagPoint lastPoint) where TQuote : IQuote
        {
            // initialize
            bool    trendUp = (lastPoint.PointType == "L");
            decimal?change  = 0;

            ZigZagPoint extremePoint = new()
            {
                Index     = lastPoint.Index,
                Value     = lastPoint.Value,
                PointType = trendUp ? "H" : "L"
            };

            // find extreme point before reversal point
            for (int i = lastPoint.Index; i < historyList.Count; i++)
            {
                TQuote h     = historyList[i];
                int    index = i + 1;

                ZigZagEval eval = GetZigZagEval(type, index, h);

                // reset extreme point
                if (trendUp)
                {
                    if (eval.High >= extremePoint.Value)
                    {
                        extremePoint.Index = eval.Index;
                        extremePoint.Value = eval.High;
                    }
                    else
                    {
                        change = (extremePoint.Value == 0) ? null
                            : (extremePoint.Value - eval.Low) / extremePoint.Value;
                    }
                }
                else
                {
                    if (eval.Low <= extremePoint.Value)
                    {
                        extremePoint.Index = eval.Index;
                        extremePoint.Value = eval.Low;
                    }
                    else
                    {
                        change = (extremePoint.Value == 0) ? null
                            : (eval.High - extremePoint.Value) / extremePoint.Value;
                    }
                }

                // return extreme point when deviation threshold met
                if (change >= changeThreshold)
                {
                    return(extremePoint);
                }
            }

            // handle last unconfirmed point
            int finalPointIndex = historyList.Count;

            if (extremePoint.Index == finalPointIndex && change < changeThreshold)
            {
                extremePoint.PointType = null;
            }

            return(extremePoint);
        }

        private static void DrawZigZagLine <TQuote>(List <ZigZagResult> results, List <TQuote> historyList,
Esempio n. 6
0
        private static ZigZagPoint EvaluateNextPoint(List <Quote> historyList,
                                                     ZigZagType type, decimal changeThreshold, ZigZagPoint lastPoint)
        {
            // initialize
            bool       trendUp = (lastPoint.PointType == "L");
            decimal    change  = 0;
            ZigZagEval eval    = new ZigZagEval();

            ZigZagPoint extremePoint = new ZigZagPoint
            {
                Index     = lastPoint.Index,
                Value     = lastPoint.Value,
                PointType = trendUp ? "H" : "L"
            };

            List <Quote> period = historyList
                                  .Where(x => x.Index > lastPoint.Index)
                                  .ToList();

            // find extreme point before reversal point
            foreach (Quote h in period)
            {
                eval = GetZigZagEval(type, h);

                // reset extreme point
                switch (trendUp)
                {
                case true:

                    if (eval.High >= extremePoint.Value)
                    {
                        extremePoint.Index = eval.Index;
                        extremePoint.Value = eval.High;
                    }
                    else
                    {
                        change = (extremePoint.Value - eval.Low) / extremePoint.Value;
                    }

                    break;

                case false:

                    if (eval.Low <= extremePoint.Value)
                    {
                        extremePoint.Index = eval.Index;
                        extremePoint.Value = eval.Low;
                    }
                    else
                    {
                        change = (eval.High - extremePoint.Value) / extremePoint.Value;
                    }

                    break;
                }

                // return extreme point when deviation threshold met
                if (change >= changeThreshold)
                {
                    return(extremePoint);
                }
            }

            // handle last unconfirmed point
            int finalPointIndex = historyList.Select(x => (int)x.Index).Max();

            if (extremePoint.Index == finalPointIndex && change < changeThreshold)
            {
                extremePoint.PointType = null;
            }

            return(extremePoint);
        }
        private void ZigZag(TreeNode rotationNode, Direction direction, ZigZagType zigZagType)
        {
            var isZigZag  = (zigZagType == ZigZagType.ZigZag);
            var newParent = rotationNode
                            .GetChild((Direction)((1 ^ (int)direction)))
                            .GetChild((Direction)(zigZagType == ZigZagType.ZigZag ? (int)direction : (1 ^ (int)direction)));

            if (rotationNode.Parent != null)
            {
                if (rotationNode.Value > rotationNode.Parent.Value)
                {
                    //rotation node is a right child
                    rotationNode.Parent.RightChild = newParent;
                }
                else
                {
                    rotationNode.Parent.LeftChild = newParent;
                }
                newParent.Parent = rotationNode.Parent;
            }
            else
            {
                //we are currently processing root node
                Root             = newParent;
                newParent.Parent = null;
            }
            var originalLeftTree  = newParent.LeftChild;
            var originalRightTree = newParent.RightChild;

            if (direction == Direction.Left)
            {
                newParent.LeftChild            = (isZigZag ? rotationNode : rotationNode.RightChild);
                newParent.RightChild           = isZigZag ? rotationNode.RightChild : newParent.RightChild;
                rotationNode.Parent            = (isZigZag ? newParent : newParent.LeftChild);
                rotationNode.RightChild.Parent = newParent;
                if (isZigZag)
                {
                    newParent.RightChild.LeftChild = originalRightTree;
                    newParent.LeftChild.RightChild = originalLeftTree;
                    if (originalRightTree != null)
                    {
                        originalRightTree.Parent = newParent.RightChild;
                    }
                    if (originalLeftTree != null)
                    {
                        originalLeftTree.Parent = newParent.LeftChild;
                    }
                }
                else
                {
                    rotationNode.RightChild.RightChild = originalLeftTree;
                    if (originalLeftTree != null)
                    {
                        originalLeftTree.Parent = rotationNode.RightChild;
                    }
                    rotationNode.RightChild = newParent.LeftChild.LeftChild;
                    if (newParent.LeftChild.LeftChild != null)
                    {
                        newParent.LeftChild.LeftChild.Parent = rotationNode;
                    }
                    newParent.LeftChild.LeftChild = rotationNode;
                }
            }
            else
            {
                newParent.RightChild          = (isZigZag ? rotationNode : rotationNode.LeftChild);
                newParent.LeftChild           = isZigZag ? rotationNode.LeftChild : newParent.LeftChild;
                rotationNode.Parent           = (isZigZag ? newParent : newParent.RightChild);
                rotationNode.LeftChild.Parent = newParent;
                if (isZigZag)
                {
                    newParent.LeftChild.RightChild = originalLeftTree;
                    newParent.RightChild.LeftChild = originalRightTree;
                    if (originalLeftTree != null)
                    {
                        originalLeftTree.Parent = newParent.LeftChild;
                    }
                    if (originalRightTree != null)
                    {
                        originalRightTree.Parent = newParent.RightChild;
                    }
                }
                else
                {
                    rotationNode.LeftChild.LeftChild = originalRightTree;
                    if (originalRightTree != null)
                    {
                        originalRightTree.Parent = rotationNode.LeftChild;
                    }
                    rotationNode.LeftChild = newParent.RightChild.RightChild;
                    if (newParent.RightChild.RightChild != null)
                    {
                        newParent.RightChild.RightChild.Parent = rotationNode;
                    }
                    newParent.RightChild.RightChild = rotationNode;
                }
            }
        }