Exemplo n.º 1
0
        private static List <ConnorsRsiResult> CalcConnorsRsiBaseline(
            List <BasicData> bdList, int rsiPeriod, int rankPeriod)
        {
            // initialize
            List <RsiResult> rsiResults = CalcRsi(bdList, rsiPeriod).ToList();

            int size = bdList.Count;
            List <ConnorsRsiResult> results = new List <ConnorsRsiResult>(size);

            decimal?[] gain = new decimal?[size];

            decimal?lastClose = null;
            decimal streak    = 0;

            // compose interim results
            for (int i = 0; i < size; i++)
            {
                BasicData h     = bdList[i];
                int       index = i + 1;

                ConnorsRsiResult result = new ConnorsRsiResult
                {
                    Date     = h.Date,
                    RsiClose = rsiResults[i].Rsi
                };

                // bypass for first record
                if (lastClose == null)
                {
                    lastClose = h.Value;
                    results.Add(result);
                    continue;
                }

                // streak of up or down
                if (h.Value == lastClose)
                {
                    streak = 0;
                }
                else if (h.Value > lastClose)
                {
                    if (streak >= 0)
                    {
                        streak++;
                    }
                    else
                    {
                        streak = 1;
                    }
                }
                else // h.Value < lastClose
                {
                    if (streak <= 0)
                    {
                        streak--;
                    }
                    else
                    {
                        streak = -1;
                    }
                }

                result.Streak = streak;

                // percentile rank
                gain[i] = (lastClose == 0) ? null
                    : (decimal)((lastClose <= 0) ? null : (h.Value - lastClose) / lastClose);

                results.Add(result);

                if (index > rankPeriod)
                {
                    int qty = 0;
                    for (int p = index - rankPeriod - 1; p < index; p++)
                    {
                        if (gain[p] < gain[i])
                        {
                            qty++;
                        }
                    }

                    result.PercentRank = 100m * qty / rankPeriod;
                }


                lastClose = h.Value;
            }

            return(results);
        }
Exemplo n.º 2
0
        // CONNORS RSI
        public static IEnumerable <ConnorsRsiResult> GetConnorsRsi(
            IEnumerable <Quote> history, int rsiPeriod = 3, int streakPeriod = 2, int rankPeriod = 100)
        {
            // convert history to basic format
            IEnumerable <BasicData> bd = Cleaners.ConvertHistoryToBasic(history, "C");

            // check parameters
            ValidateConnorsRsi(bd, rsiPeriod, streakPeriod, rankPeriod);

            // initialize
            List <ConnorsRsiResult> results    = new List <ConnorsRsiResult>();
            IEnumerable <RsiResult> rsiResults = CalcRsi(bd, rsiPeriod);
            int startPeriod = Math.Max(rsiPeriod, Math.Max(streakPeriod, rankPeriod)) + 2;

            decimal?lastClose = null;
            decimal streak    = 0;

            // compose interim results
            foreach (BasicData h in bd)
            {
                ConnorsRsiResult result = new ConnorsRsiResult
                {
                    Index    = (int)h.Index,
                    Date     = h.Date,
                    RsiClose = rsiResults.Where(x => x.Index == h.Index).FirstOrDefault().Rsi
                };

                // bypass for first record
                if (lastClose == null)
                {
                    lastClose = h.Value;
                    results.Add(result);
                    continue;
                }

                // streak of up or down
                if (h.Value == lastClose)
                {
                    streak = 0;
                }
                else if (h.Value > lastClose)
                {
                    if (streak >= 0)
                    {
                        streak++;
                    }
                    else
                    {
                        streak = 1;
                    }
                }
                else // h.Value < lastClose
                {
                    if (streak <= 0)
                    {
                        streak--;
                    }
                    else
                    {
                        streak = -1;
                    }
                }

                result.Streak = streak;

                // percentile rank
                result.PeriodGain = (decimal)((lastClose <= 0) ? null : (h.Value - lastClose) / lastClose);

                if (h.Index > rankPeriod)
                {
                    IEnumerable <ConnorsRsiResult> period = results
                                                            .Where(x => x.Index >= (h.Index - rankPeriod) && x.Index < h.Index);

                    result.PercentRank = (decimal)100 * period
                                         .Where(x => x.PeriodGain < result.PeriodGain).Count() / rankPeriod;
                }

                results.Add(result);
                lastClose = h.Value;
            }

            // RSI of streak
            List <BasicData> bdStreak = results
                                        .Where(x => x.Streak != null)
                                        .Select(x => new BasicData {
                Index = null, Date = x.Date, Value = (decimal)x.Streak
            })
                                        .ToList();

            IEnumerable <RsiResult> rsiStreakResults = CalcRsi(bdStreak, streakPeriod);

            // compose final results
            foreach (ConnorsRsiResult r in results.Where(x => x.Index >= streakPeriod + 2))
            {
                r.RsiStreak = rsiStreakResults
                              .Where(x => x.Index == r.Index - 1)
                              .FirstOrDefault()
                              .Rsi;

                if (r.Index >= startPeriod)
                {
                    r.ConnorsRsi = (r.RsiClose + r.RsiStreak + r.PercentRank) / 3;
                }
            }

            return(results);
        }