예제 #1
0
        // EXPONENTIAL MOVING AVERAGE
        public static IEnumerable <EmaResult> GetEma(IEnumerable <Quote> history, int lookbackPeriod)
        {
            // convert history to basic format
            IEnumerable <BasicData> bd = Cleaners.ConvertHistoryToBasic(history, "C");

            // calculate
            return(CalcEma(bd, lookbackPeriod));
        }
예제 #2
0
        // RELATIVE STRENGTH INDEX
        public static IEnumerable <RsiResult> GetRsi(IEnumerable <Quote> history, int lookbackPeriod = 14)
        {
            // convert history to basic format
            List <BasicData> bd = Cleaners.ConvertHistoryToBasic(history, "C");

            // calculate
            return(CalcRsi(bd, lookbackPeriod));
        }
예제 #3
0
        // STANDARD DEVIATION
        public static IEnumerable <StdDevResult> GetStdDev(IEnumerable <Quote> history, int lookbackPeriod)
        {
            // convert to basic data
            IEnumerable <BasicData> bd = Cleaners.ConvertHistoryToBasic(history, "C");

            // calculate
            return(CalcStdDev(bd, lookbackPeriod));
        }
예제 #4
0
        // TRIPLE EXPONENTIAL MOVING AVERAGE
        public static IEnumerable <EmaResult> GetTripleEma <TQuote>(
            IEnumerable <TQuote> history,
            int lookbackPeriod)
            where TQuote : IQuote
        {
            // convert history to basic format
            List <BasicData> bdList = Cleaners.ConvertHistoryToBasic(history, "C");

            // validate parameters
            ValidateTema(bdList, lookbackPeriod);

            // initialize
            List <EmaResult> results = new List <EmaResult>(bdList.Count);
            List <EmaResult> emaN1   = CalcEma(bdList, lookbackPeriod).ToList();

            List <BasicData> bd2 = emaN1
                                   .Where(x => x.Ema != null)
                                   .Select(x => new BasicData {
                Date = x.Date, Value = (decimal)x.Ema
            })
                                   .ToList();

            List <EmaResult> emaN2 = CalcEma(bd2, lookbackPeriod).ToList();

            List <BasicData> bd3 = emaN2
                                   .Where(x => x.Ema != null)
                                   .Select(x => new BasicData {
                Date = x.Date, Value = (decimal)x.Ema
            })
                                   .ToList();

            List <EmaResult> emaN3 = CalcEma(bd3, lookbackPeriod).ToList();

            // compose final results
            for (int i = 0; i < emaN1.Count; i++)
            {
                EmaResult e1    = emaN1[i];
                int       index = i + 1;

                EmaResult result = new EmaResult
                {
                    Date = e1.Date
                };

                if (index >= 3 * lookbackPeriod - 2)
                {
                    EmaResult e2 = emaN2[index - lookbackPeriod];
                    EmaResult e3 = emaN3[index - 2 * lookbackPeriod + 1];

                    result.Ema = 3 * e1.Ema - 3 * e2.Ema + e3.Ema;
                }

                results.Add(result);
            }

            return(results);
        }
예제 #5
0
        // EXPONENTIAL MOVING AVERAGE
        public static IEnumerable <EmaResult> GetEma <TQuote>(
            IEnumerable <TQuote> history,
            int lookbackPeriod)
            where TQuote : IQuote
        {
            // convert history to basic format
            List <BasicData> bdList = Cleaners.ConvertHistoryToBasic(history, "C");

            // calculate
            return(CalcEma(bdList, lookbackPeriod));
        }
예제 #6
0
        // STANDARD DEVIATION
        public static IEnumerable <StdDevResult> GetStdDev <TQuote>(
            IEnumerable <TQuote> history,
            int lookbackPeriod,
            int?smaPeriod = null)
            where TQuote : IQuote
        {
            // convert to basic data
            List <BasicData> bd = Cleaners.ConvertHistoryToBasic(history, "C");

            // calculate
            return(CalcStdDev(bd, lookbackPeriod, smaPeriod));
        }
예제 #7
0
        // DOUBLE EXPONENTIAL MOVING AVERAGE
        public static IEnumerable <EmaResult> GetDoubleEma <TQuote>(
            IEnumerable <TQuote> history,
            int lookbackPeriod)
            where TQuote : IQuote
        {
            // convert history to basic format
            List <BasicData> bd = Cleaners.ConvertHistoryToBasic(history, "C");

            // validate parameters
            ValidateDema(bd, lookbackPeriod);

            // initialize
            List <EmaResult> results = new List <EmaResult>();
            List <EmaResult> emaN    = CalcEma(bd, lookbackPeriod).ToList();

            List <BasicData> bd2 = emaN
                                   .Where(x => x.Ema != null)
                                   .Select(x => new BasicData {
                Date = x.Date, Value = (decimal)x.Ema
            })
                                   .ToList(); // note: ToList seems to be required when changing data

            List <EmaResult> emaN2 = CalcEma(bd2, lookbackPeriod).ToList();

            // compose final results
            for (int i = 0; i < emaN.Count; i++)
            {
                EmaResult e1    = emaN[i];
                int       index = i + 1;

                EmaResult result = new EmaResult
                {
                    Date = e1.Date
                };

                if (index >= 2 * lookbackPeriod - 1)
                {
                    EmaResult e2 = emaN2[index - lookbackPeriod];
                    result.Ema = 2 * e1.Ema - e2.Ema;
                }

                results.Add(result);
            }

            return(results);
        }
예제 #8
0
        // CONNORS RSI
        public static IEnumerable <ConnorsRsiResult> GetConnorsRsi <TQuote>(
            IEnumerable <TQuote> history,
            int rsiPeriod    = 3,
            int streakPeriod = 2,
            int rankPeriod   = 100)
            where TQuote : IQuote
        {
            // convert history to basic format
            List <BasicData> bd = Cleaners.ConvertHistoryToBasic(history, "C").ToList();

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

            // initialize
            List <ConnorsRsiResult> results = CalcConnorsRsiBaseline(bd, rsiPeriod, rankPeriod);
            int startPeriod = Math.Max(rsiPeriod, Math.Max(streakPeriod, rankPeriod)) + 2;

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

            List <RsiResult> rsiStreakResults = CalcRsi(bdStreak, streakPeriod).ToList();

            // compose final results
            for (int p = streakPeriod + 2; p < results.Count; p++)
            {
                ConnorsRsiResult r = results[p];
                RsiResult        k = rsiStreakResults[p - 1];

                r.RsiStreak = k.Rsi;

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

            return(results);
        }
예제 #9
0
        // DOUBLE EXPONENTIAL MOVING AVERAGE
        public static IEnumerable <EmaResult> GetDoubleEma(IEnumerable <Quote> history, int lookbackPeriod)
        {
            // convert history to basic format
            IEnumerable <BasicData> bd = Cleaners.ConvertHistoryToBasic(history, "C");

            // validate parameters
            ValidateDema(bd, lookbackPeriod);

            // initialize
            List <EmaResult>        results = new List <EmaResult>();
            IEnumerable <EmaResult> emaN    = CalcEma(bd, lookbackPeriod);

            List <BasicData> bd2 = emaN
                                   .Where(x => x.Ema != null)
                                   .Select(x => new BasicData {
                Index = null, Date = x.Date, Value = (decimal)x.Ema
            })
                                   .ToList(); // note: ToList seems to be required when changing data

            IEnumerable <EmaResult> emaN2 = CalcEma(bd2, lookbackPeriod);

            // compose final results
            foreach (EmaResult h in emaN)
            {
                EmaResult result = new EmaResult
                {
                    Index = h.Index,
                    Date  = h.Date
                };

                if (h.Index >= 2 * lookbackPeriod)
                {
                    EmaResult emaEma = emaN2.Where(x => x.Index == h.Index - lookbackPeriod + 1).FirstOrDefault();
                    result.Ema = 2 * h.Ema - emaEma.Ema;
                }

                results.Add(result);
            }

            return(results);
        }
예제 #10
0
        // MOVING AVERAGE CONVERGENCE/DIVERGENCE (MACD) OSCILLATOR
        public static IEnumerable <MacdResult> GetMacd <TQuote>(
            IEnumerable <TQuote> history,
            int fastPeriod   = 12,
            int slowPeriod   = 26,
            int signalPeriod = 9)
            where TQuote : IQuote
        {
            // convert history to basic format
            List <BasicData> bdList = Cleaners.ConvertHistoryToBasic(history, "C");

            // check parameter arguments
            ValidateMacd(history, fastPeriod, slowPeriod, signalPeriod);

            // initialize
            List <EmaResult> emaFast = CalcEma(bdList, fastPeriod).ToList();
            List <EmaResult> emaSlow = CalcEma(bdList, slowPeriod).ToList();

            int size = bdList.Count;
            List <BasicData>  emaDiff = new List <BasicData>();
            List <MacdResult> results = new List <MacdResult>(size);

            // roll through history
            for (int i = 0; i < size; i++)
            {
                BasicData h  = bdList[i];
                EmaResult df = emaFast[i];
                EmaResult ds = emaSlow[i];

                MacdResult result = new MacdResult
                {
                    Date = h.Date
                };

                if (df?.Ema != null && ds?.Ema != null)
                {
                    decimal macd = (decimal)df.Ema - (decimal)ds.Ema;
                    result.Macd = macd;

                    // temp data for interim EMA of macd
                    BasicData diff = new BasicData
                    {
                        Date  = h.Date,
                        Value = macd
                    };

                    emaDiff.Add(diff);
                }

                results.Add(result);
            }

            // add signal and histogram to result
            List <EmaResult> emaSignal = CalcEma(emaDiff, signalPeriod).ToList();

            for (int d = slowPeriod - 1; d < size; d++)
            {
                MacdResult r  = results[d];
                EmaResult  ds = emaSignal[d + 1 - slowPeriod];

                r.Signal    = ds.Ema;
                r.Histogram = r.Macd - r.Signal;
            }

            return(results);
        }
예제 #11
0
        // TRIPLE EMA OSCILLATOR (TRIX)
        public static IEnumerable <TrixResult> GetTrix <TQuote>(
            IEnumerable <TQuote> history,
            int lookbackPeriod,
            int?signalPeriod = null)
            where TQuote : IQuote
        {
            // convert history to basic format
            List <BasicData> bdList = Cleaners.ConvertHistoryToBasic(history, "C");

            // validate parameters
            ValidateTrix(bdList, lookbackPeriod);

            // initialize
            List <TrixResult> results = new List <TrixResult>(bdList.Count);
            decimal?          lastEma = null;

            List <EmaResult> emaN1 = CalcEma(bdList, lookbackPeriod).ToList();

            List <BasicData> bd2 = emaN1
                                   .Where(x => x.Ema != null)
                                   .Select(x => new BasicData {
                Date = x.Date, Value = (decimal)x.Ema
            })
                                   .ToList();

            List <EmaResult> emaN2 = CalcEma(bd2, lookbackPeriod).ToList();

            List <BasicData> bd3 = emaN2
                                   .Where(x => x.Ema != null)
                                   .Select(x => new BasicData {
                Date = x.Date, Value = (decimal)x.Ema
            })
                                   .ToList();

            List <EmaResult> emaN3 = CalcEma(bd3, lookbackPeriod).ToList();

            // compose final results
            for (int i = 0; i < emaN1.Count; i++)
            {
                EmaResult e1    = emaN1[i];
                int       index = i + 1;

                TrixResult result = new TrixResult
                {
                    Date = e1.Date
                };

                results.Add(result);

                if (index >= 3 * lookbackPeriod - 2)
                {
                    EmaResult e2 = emaN2[index - lookbackPeriod];
                    EmaResult e3 = emaN3[index - 2 * lookbackPeriod + 1];

                    result.Ema3 = e3.Ema;

                    if (lastEma != null && lastEma != 0)
                    {
                        result.Trix = 100 * (e3.Ema - lastEma) / lastEma;
                    }

                    lastEma = e3.Ema;

                    // optional SMA signal
                    GetTrixSignal(signalPeriod, index, lookbackPeriod, results);
                }
            }

            return(results);
        }
예제 #12
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
            List <BasicData> bd = Cleaners.ConvertHistoryToBasic(history, "C").ToList();

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

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

            decimal?lastClose = null;
            decimal streak    = 0;

            // compose interim results
            for (int i = 0; i < bd.Count; i++)
            {
                BasicData h = bd[i];

                ConnorsRsiResult result = new ConnorsRsiResult
                {
                    Index    = (int)h.Index,
                    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
                result.PeriodGain = (decimal)((lastClose <= 0) ? null : (h.Value - lastClose) / lastClose);

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

                    result.PercentRank = 100m * 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);
        }
예제 #13
0
        // TRIPLE EMA OSCILLATOR (TRIX)
        public static IEnumerable <TrixResult> GetTrix(
            IEnumerable <Quote> history, int lookbackPeriod, int?signalPeriod = null)
        {
            // convert history to basic format
            IEnumerable <BasicData> bd = Cleaners.ConvertHistoryToBasic(history, "C");

            // validate parameters
            ValidateTrix(bd, lookbackPeriod);

            // initialize
            List <TrixResult> results = new List <TrixResult>();
            decimal?          lastEma = null;

            List <EmaResult> emaN1 = CalcEma(bd, lookbackPeriod).ToList();

            List <BasicData> bd2 = emaN1
                                   .Where(x => x.Ema != null)
                                   .Select(x => new BasicData {
                Index = null, Date = x.Date, Value = (decimal)x.Ema
            })
                                   .ToList();

            List <EmaResult> emaN2 = CalcEma(bd2, lookbackPeriod).ToList();

            List <BasicData> bd3 = emaN2
                                   .Where(x => x.Ema != null)
                                   .Select(x => new BasicData {
                Index = null, Date = x.Date, Value = (decimal)x.Ema
            })
                                   .ToList();

            List <EmaResult> emaN3 = CalcEma(bd3, lookbackPeriod).ToList();

            // compose final results
            for (int i = 0; i < emaN1.Count; i++)
            {
                EmaResult e1 = emaN1[i];

                TrixResult result = new TrixResult
                {
                    Index = e1.Index,
                    Date  = e1.Date
                };

                results.Add(result);

                if (e1.Index >= 3 * lookbackPeriod - 2)
                {
                    EmaResult e2 = emaN2[e1.Index - lookbackPeriod];
                    EmaResult e3 = emaN3[e2.Index - lookbackPeriod];

                    result.Ema3 = e3.Ema;

                    if (lastEma != null && lastEma != 0)
                    {
                        result.Trix = 100 * (e3.Ema - lastEma) / lastEma;
                    }

                    lastEma = e3.Ema;

                    // optional SMA
                    if (signalPeriod != null && e1.Index >= 3 * lookbackPeriod - 2 + signalPeriod)
                    {
                        decimal sumSma = 0m;
                        for (int p = e1.Index - (int)signalPeriod; p < e1.Index; p++)
                        {
                            sumSma += (decimal)results[p].Trix;
                        }

                        result.Signal = sumSma / signalPeriod;
                    }
                }
            }

            return(results);
        }