Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sourceDataCount"></param>
        /// <param name="periodExtremum"></param>
        /// <param name="maxPastExtremum"></param>
        /// <param name="getSourcePrice"></param>
        /// <param name="getIndexPrice"></param>
        /// <param name="waitOneBar">ждать одного бара перед отрисовкой стрелки, закрывающегося ниже (для макс) или выше (для мин)</param>
        /// <param name="divergenceSign">поиск дивергенции? или - конвергенции?</param>
        /// <returns></returns>
        public static List <DiverSpan> FindDivergencePointsClassic(
            int sourceDataCount,
            int periodExtremum,
            int maxPastExtremum,
            GetPrice getSourcePrice,
            GetPrice getIndexPrice,
            bool waitOneBar,
            DivergenceSign divergenceSign)
        {
            var diverPairs = new List <DiverSpan>();
            var srcCount   = sourceDataCount;

            // найти экстремумы
            var extremums = new List <Point>(); // index - sign

            for (var i = periodExtremum; i < srcCount - periodExtremum - 1; i++)
            {
                bool isPeak = true, isLow = true;
                var  price = getSourcePrice(i);
                for (var j = i - periodExtremum; j <= i + periodExtremum; j++)
                {
                    if (j == i)
                    {
                        continue;
                    }
                    var priceNear = getSourcePrice(j);
                    if (priceNear > price)
                    {
                        isPeak = false;
                    }
                    if (priceNear < price)
                    {
                        isLow = false;
                    }
                    if (!isPeak && isLow == false)
                    {
                        break;
                    }
                }
                if (isPeak)
                {
                    extremums.Add(new Point(i, 1));
                }
                if (isLow)
                {
                    extremums.Add(new Point(i, -1));
                }
            }

            // от каждого экстремума поиск вперед до M баров - поиск экстремума на интервале [i-N...i+1]
            foreach (var extr in extremums)
            {
                var signExtr  = extr.Y;
                var indexExtr = extr.X;
                var priceExtr = getSourcePrice(indexExtr);

                //for (var i = extr.X + 1; i <= (extr.X + MaxPastExtremum); i++)
                for (var i = extr.X + periodExtremum; i <= (extr.X + maxPastExtremum); i++)
                {
                    // не выйти за пределы интервала, если нужен бар подтверждения - остановиться за бар до конца интервала
                    if (i > (srcCount - 1) || (waitOneBar && i == (srcCount - 1)))
                    {
                        break;
                    }
                    // новый "экстремум" должен быть выше старого
                    var price = getSourcePrice(i);
                    if ((signExtr > 0 && price <= priceExtr) ||
                        (signExtr < 0 && price >= priceExtr))
                    {
                        continue;
                    }
                    // за новым "экстремумом" должна следовать точка ниже (выше для минимума)
                    if (waitOneBar)
                    {
                        var nextPrice = getSourcePrice(i + 1);
                        if ((signExtr > 0 && price <= nextPrice) ||
                            (signExtr < 0 && price >= nextPrice))
                        {
                            continue;
                        }
                    }
                    // сравнение с дельтой индекса
                    // !! смещение индекса
                    var indexPriceI  = getIndexPrice(i);
                    var indexPriceEx = getIndexPrice(indexExtr);
                    var deltaIndex   = (double.IsNaN(indexPriceI) || double.IsNaN(indexPriceEx))
                        ? 0
                        : indexPriceI - indexPriceEx;
                    var signDelta = double.IsNaN(deltaIndex) ? 0 : Math.Sign(deltaIndex);
                    if ((divergenceSign == DivergenceSign.Divergence && signExtr == signDelta) ||
                        (divergenceSign == DivergenceSign.Convergence && signExtr != signDelta))
                    {
                        continue;
                    }
                    // экстремум найден
                    priceExtr = price;
                    diverPairs.Add(new DiverSpan(indexExtr, i, -signExtr));
                }
            }

            return(diverPairs);
        }
Пример #2
0
        public static List <DiverSpan> FindDivergencePointsQuasi(
            int sourceDataCount,
            double marginUpper,
            double marginLower,
            GetPrice getSourcePrice,
            GetPrice getIndexPrice,
            DivergenceSign divergenceSign)
        {
            var divers   = new List <DiverSpan>();
            var srcCount = sourceDataCount;

            double?lastPeak     = null;
            var    peakPrice    = 0.0;
            var    extremumSign = 0;
            var    startIndex   = 0;

            for (var i = 0; i < srcCount; i++)
            {
                var index     = getIndexPrice(i);
                var indexNext = i < srcCount?getIndexPrice(i + 1) : index;

                // если находимся в зоне перекупленности / перепроданности,
                // если след. точка ниже (выше для перепроданности),
                // если текущая точка выше последнего максимума (ниже минимума...)

                var margUp = index >= marginUpper;
                var margDn = index <= marginLower;

                if ((margUp && indexNext < index &&
                     index > (lastPeak.HasValue ? lastPeak.Value : double.MinValue)) ||
                    (margDn && indexNext > index && index < (lastPeak.HasValue ? lastPeak.Value : double.MaxValue)))
                {// + или - экстремум
                    peakPrice    = getSourcePrice(i);
                    extremumSign = margUp ? 1 : -1;
                    startIndex   = i;
                    lastPeak     = index;
                    continue;
                }
                if (!margUp && margDn == false)
                {// конец отсчета экстремума
                    extremumSign = 0;
                    lastPeak     = null;
                    continue;
                }
                // отсчет экстремума - сравнить дельту цены и дельту индекса
                var deltaPrice = getSourcePrice(i) - peakPrice;
                var deltaIndex = index - lastPeak;
                if (divergenceSign == DivergenceSign.Convergence)
                {
                    deltaIndex = -deltaIndex;
                }

                if (extremumSign > 0)
                {
                    if (deltaPrice > 0 && deltaIndex < 0)
                    // медвежий дивер
                    {
                        divers.Add(new DiverSpan(startIndex, i, -1));
                        peakPrice = getSourcePrice(i);
                    }
                }
                if (extremumSign < 0)
                {
                    if (deltaPrice < 0 && deltaIndex > 0)
                    // бычий дивер
                    {
                        divers.Add(new DiverSpan(startIndex, i, 1));
                        peakPrice = getSourcePrice(i);
                    }
                }
            }
            return(divers);
        }