// 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 = history.ConvertToBasic("C");

            // check parameter arguments
            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);
        }
Exemple #2
0
        // TRIPLE EXPONENTIAL MOVING AVERAGE
        public static IEnumerable <EmaResult> GetTripleEma(IEnumerable <Quote> history, int lookbackPeriod)
        {
            // convert history to basic format
            IEnumerable <BasicData> bd = Cleaners.ConvertHistoryToBasic(history, "C");

            // validate parameters
            ValidateTema(bd, lookbackPeriod);

            // initialize
            List <EmaResult> results = new List <EmaResult>();
            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];

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

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

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

                results.Add(result);
            }

            return(results);
        }
        // SIMPLE MOVING AVERAGE
        public static IEnumerable <ChaikinOscResult> GetChaikinOsc(
            IEnumerable <Quote> history,
            int fastPeriod = 3,
            int slowPeriod = 10)
        {
            // clean quotes
            history = Cleaners.PrepareHistory(history);

            // check parameters
            ValidateChaikinOsc(history, fastPeriod, slowPeriod);

            // initialize
            List <ChaikinOscResult> results    = new List <ChaikinOscResult>();
            IEnumerable <AdlResult> adlResults = GetAdl(history);


            // EMA of ADL
            IEnumerable <BasicData> adlBasicData = adlResults
                                                   .Select(x => new BasicData {
                Index = x.Index, Date = x.Date, Value = x.Adl
            });

            IEnumerable <EmaResult> adlEmaSlow = CalcEma(adlBasicData, slowPeriod);
            IEnumerable <EmaResult> adlEmaFast = CalcEma(adlBasicData, fastPeriod);


            // roll through history
            foreach (AdlResult r in adlResults)
            {
                ChaikinOscResult result = new ChaikinOscResult
                {
                    Index = r.Index,
                    Date  = r.Date,
                    MoneyFlowMultiplier = r.MoneyFlowMultiplier,
                    MoneyFlowVolume     = r.MoneyFlowVolume,
                    Adl = r.Adl
                };

                // add Oscillator
                if (r.Index >= slowPeriod)
                {
                    EmaResult f = adlEmaFast.Where(x => x.Index == r.Index).FirstOrDefault();
                    EmaResult s = adlEmaSlow.Where(x => x.Index == r.Index).FirstOrDefault();

                    result.Oscillator = f.Ema - s.Ema;
                }

                results.Add(result);
            }

            return(results);
        }
        // SIMPLE MOVING AVERAGE
        public static IEnumerable <ChaikinOscResult> GetChaikinOsc(
            IEnumerable <Quote> history,
            int fastPeriod = 3,
            int slowPeriod = 10)
        {
            // clean quotes
            Cleaners.PrepareHistory(history);

            // check parameters
            ValidateChaikinOsc(history, fastPeriod, slowPeriod);

            // initialize
            IEnumerable <AdlResult> adlResults = GetAdl(history);

            // money flow
            List <ChaikinOscResult> results = adlResults
                                              .Select(r => new ChaikinOscResult
            {
                Index = r.Index,
                Date  = r.Date,
                MoneyFlowMultiplier = r.MoneyFlowMultiplier,
                MoneyFlowVolume     = r.MoneyFlowVolume,
                Adl = r.Adl
            })
                                              .ToList();

            // EMA of ADL
            IEnumerable <BasicData> adlBasicData = adlResults
                                                   .Select(x => new BasicData {
                Index = x.Index, Date = x.Date, Value = x.Adl
            });

            List <EmaResult> adlEmaSlow = CalcEma(adlBasicData, slowPeriod).ToList();
            List <EmaResult> adlEmaFast = CalcEma(adlBasicData, fastPeriod).ToList();

            // add Oscillator
            for (int i = slowPeriod - 1; i < results.Count; i++)
            {
                ChaikinOscResult r = results[i];

                EmaResult f = adlEmaFast[i];
                EmaResult s = adlEmaSlow[i];

                r.Oscillator = f.Ema - s.Ema;
            }

            return(results);
        }
Exemple #5
0
        // EXPONENTIAL MOVING AVERAGE
        public static IEnumerable <EmaResult> GetEma(IEnumerable <Quote> history, int lookbackPeriod)
        {
            // clean quotes
            history = Cleaners.PrepareHistory(history);

            // check exceptions
            int qtyHistory = history.Count();
            int minHistory = 2 * lookbackPeriod;

            if (qtyHistory < minHistory)
            {
                throw new BadHistoryException("Insufficient history provided for EMA.  " +
                                              string.Format("You provided {0} periods of history when {1} is required.  "
                                                            + "Since this uses a smoothing technique, "
                                                            + "we recommend you use at least 250 data points prior to the intended "
                                                            + "usage date for maximum precision.", qtyHistory, minHistory));
            }

            // initialize
            List <EmaResult> results = new List <EmaResult>();

            // initialize EMA
            decimal k       = 2 / (decimal)(lookbackPeriod + 1);
            decimal lastEma = history
                              .Where(x => x.Index < lookbackPeriod)
                              .Select(x => x.Close)
                              .Average();

            // roll through history
            foreach (Quote h in history)
            {
                EmaResult result = new EmaResult
                {
                    Index = (int)h.Index,
                    Date  = h.Date
                };

                if (h.Index >= lookbackPeriod)
                {
                    result.Ema = lastEma + k * (h.Close - lastEma);
                    lastEma    = (decimal)result.Ema;
                }

                results.Add(result);
            }

            return(results);
        }
Exemple #6
0
        // DONCHIAN CHANNEL
        public static IEnumerable <KeltnerResult> GetKeltner(
            IEnumerable <Quote> history, int emaPeriod = 20, decimal multiplier = 2, int atrPeriod = 10)
        {
            // clean quotes
            history = Cleaners.PrepareHistory(history);

            // validate parameters
            ValidateKeltner(history, emaPeriod, multiplier, atrPeriod);

            // initialize
            List <KeltnerResult>    results    = new List <KeltnerResult>();
            IEnumerable <EmaResult> emaResults = GetEma(history, emaPeriod);
            IEnumerable <AtrResult> atrResults = GetAtr(history, atrPeriod);
            int lookbackPeriod = Math.Max(emaPeriod, atrPeriod);

            decimal?prevWidth = null;

            // roll through history
            foreach (Quote h in history)
            {
                KeltnerResult result = new KeltnerResult
                {
                    Index = (int)h.Index,
                    Date  = h.Date
                };

                if (h.Index >= lookbackPeriod)
                {
                    IEnumerable <Quote> period = history
                                                 .Where(x => x.Index > (h.Index - lookbackPeriod) && x.Index <= h.Index);

                    EmaResult ema = emaResults.Where(x => x.Index == h.Index).FirstOrDefault();
                    AtrResult atr = atrResults.Where(x => x.Index == h.Index).FirstOrDefault();

                    result.UpperBand  = ema.Ema + multiplier * atr.Atr;
                    result.LowerBand  = ema.Ema - multiplier * atr.Atr;
                    result.Centerline = ema.Ema;
                    result.Width      = (result.Centerline == 0) ? null : (result.UpperBand - result.LowerBand) / result.Centerline;

                    // for next iteration
                    prevWidth = result.Width;
                }

                results.Add(result);
            }

            return(results);
        }
Exemple #7
0
        // DONCHIAN CHANNEL
        public static IEnumerable <KeltnerResult> GetKeltner <TQuote>(
            IEnumerable <TQuote> history,
            int emaPeriod      = 20,
            decimal multiplier = 2,
            int atrPeriod      = 10)
            where TQuote : IQuote
        {
            // clean quotes
            List <TQuote> historyList = history.Sort();

            // validate parameters
            ValidateKeltner(history, emaPeriod, multiplier, atrPeriod);

            // initialize
            List <KeltnerResult> results    = new List <KeltnerResult>();
            List <EmaResult>     emaResults = GetEma(history, emaPeriod).ToList();
            List <AtrResult>     atrResults = GetAtr(history, atrPeriod).ToList();
            int lookbackPeriod = Math.Max(emaPeriod, atrPeriod);

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

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

                if (index >= lookbackPeriod)
                {
                    EmaResult ema = emaResults[i];
                    AtrResult atr = atrResults[i];

                    result.UpperBand  = ema.Ema + multiplier * atr.Atr;
                    result.LowerBand  = ema.Ema - multiplier * atr.Atr;
                    result.Centerline = ema.Ema;
                    result.Width      = (result.Centerline == 0) ? null
                        : (result.UpperBand - result.LowerBand) / result.Centerline;
                }

                results.Add(result);
            }

            return(results);
        }
Exemple #8
0
        // DOUBLE EXPONENTIAL MOVING AVERAGE
        /// <include file='./info.xml' path='indicators/type[@name="DEMA"]/*' />
        ///
        public static IEnumerable <EmaResult> GetDoubleEma <TQuote>(
            this IEnumerable <TQuote> history,
            int lookbackPeriod)
            where TQuote : IQuote
        {
            // convert history to basic format
            List <BasicData> bdList = history.ConvertToBasic("C");

            // check parameter arguments
            ValidateDema(bdList, lookbackPeriod);

            // initialize
            List <EmaResult> results = new(bdList.Count);
            List <EmaResult> emaN    = CalcEma(bdList, 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()
                {
                    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);
        }
Exemple #9
0
        private static IEnumerable <EmaResult> CalcEma(
            List <BasicData> bdList, int lookbackPeriod)
        {
            // check parameter arguments
            ValidateEma(bdList, lookbackPeriod);

            // initialize
            List <EmaResult> results = new List <EmaResult>(bdList.Count);

            decimal k       = 2 / (decimal)(lookbackPeriod + 1);
            decimal lastEma = 0;

            for (int i = 0; i < lookbackPeriod; i++)
            {
                lastEma += bdList[i].Value;
            }
            lastEma /= lookbackPeriod;

            // roll through history
            for (int i = 0; i < bdList.Count; i++)
            {
                BasicData h     = bdList[i];
                int       index = i + 1;

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

                if (index > lookbackPeriod)
                {
                    result.Ema = lastEma + k * (h.Value - lastEma);
                    lastEma    = (decimal)result.Ema;
                }
                else if (index == lookbackPeriod)
                {
                    result.Ema = lastEma;
                }

                results.Add(result);
            }

            return(results);
        }
Exemple #10
0
        // CHAIKIN OSCILLATOR
        public static IEnumerable <ChaikinOscResult> GetChaikinOsc <TQuote>(
            IEnumerable <TQuote> history,
            int fastPeriod = 3,
            int slowPeriod = 10)
            where TQuote : IQuote
        {
            // check parameters
            ValidateChaikinOsc(history, fastPeriod, slowPeriod);

            // money flow
            List <ChaikinOscResult> results = GetAdl(history)
                                              .Select(r => new ChaikinOscResult
            {
                Date = r.Date,
                MoneyFlowMultiplier = r.MoneyFlowMultiplier,
                MoneyFlowVolume     = r.MoneyFlowVolume,
                Adl = r.Adl
            })
                                              .ToList();

            // EMA of ADL
            List <BasicData> adlBasicData = results
                                            .Select(x => new BasicData {
                Date = x.Date, Value = x.Adl
            })
                                            .ToList();

            List <EmaResult> adlEmaSlow = CalcEma(adlBasicData, slowPeriod).ToList();
            List <EmaResult> adlEmaFast = CalcEma(adlBasicData, fastPeriod).ToList();

            // add Oscillator
            for (int i = slowPeriod - 1; i < results.Count; i++)
            {
                ChaikinOscResult r = results[i];

                EmaResult f = adlEmaFast[i];
                EmaResult s = adlEmaSlow[i];

                r.Oscillator = f.Ema - s.Ema;
            }

            return(results);
        }
Exemple #11
0
        private static IEnumerable <EmaResult> CalcEma(IEnumerable <BasicData> basicData, int lookbackPeriod)
        {
            // clean quotes
            basicData = Cleaners.PrepareBasicData(basicData);

            // validate parameters
            ValidateEma(basicData, lookbackPeriod);

            // initialize
            List <EmaResult> results = new List <EmaResult>();

            // initialize EMA
            decimal k       = 2 / (decimal)(lookbackPeriod + 1);
            decimal lastEma = basicData
                              .Where(x => x.Index <= lookbackPeriod)
                              .ToList()
                              .Select(x => x.Value)
                              .Average();

            // roll through history
            foreach (BasicData h in basicData)
            {
                EmaResult result = new EmaResult
                {
                    Index = (int)h.Index,
                    Date  = h.Date
                };

                if (h.Index > lookbackPeriod)
                {
                    result.Ema = lastEma + k * (h.Value - lastEma);
                    lastEma    = (decimal)result.Ema;
                }
                else if (h.Index == lookbackPeriod)
                {
                    result.Ema = lastEma;
                }

                results.Add(result);
            }

            return(results);
        }
Exemple #12
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>();
            List <EmaResult> emaN    = CalcEma(bd, lookbackPeriod).ToList();

            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

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

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

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

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

                results.Add(result);
            }

            return(results);
        }
        // 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);
        }
Exemple #14
0
        // EXPONENTIAL MOVING AVERAGE
        public static IEnumerable <EmaResult> GetEma(IEnumerable <Quote> history, int lookbackPeriod)
        {
            // clean quotes
            history = Cleaners.PrepareHistory(history);

            // validate parameters
            ValidateEma(history, lookbackPeriod);

            // initialize
            List <EmaResult> results = new List <EmaResult>();

            // initialize EMA
            decimal k       = 2 / (decimal)(lookbackPeriod + 1);
            decimal lastEma = history
                              .Where(x => x.Index < lookbackPeriod)
                              .Select(x => x.Close)
                              .Average();

            // roll through history
            foreach (Quote h in history)
            {
                EmaResult result = new EmaResult
                {
                    Index = (int)h.Index,
                    Date  = h.Date
                };

                if (h.Index >= lookbackPeriod)
                {
                    result.Ema = lastEma + k * (h.Close - lastEma);
                    lastEma    = (decimal)result.Ema;
                }

                results.Add(result);
            }

            return(results);
        }
Exemple #15
0
        // MOVING AVERAGE CONVERGENCE/DIVERGENCE (MACD) OSCILLATOR
        public static IEnumerable <MacdResult> GetMacd(IEnumerable <Quote> history, int fastPeriod = 12, int slowPeriod = 26, int signalPeriod = 9)
        {
            // clean quotes
            history = Cleaners.PrepareHistory(history);

            // check parameters
            ValidateMacd(history, fastPeriod, slowPeriod, signalPeriod);

            // initialize
            IEnumerable <EmaResult> emaFast = GetEma(history, fastPeriod);
            IEnumerable <EmaResult> emaSlow = GetEma(history, slowPeriod);

            List <BasicData>  emaDiff = new List <BasicData>();
            List <MacdResult> results = new List <MacdResult>();

            foreach (Quote h in history)
            {
                EmaResult df = emaFast.Where(x => x.Date == h.Date).FirstOrDefault();
                EmaResult ds = emaSlow.Where(x => x.Date == h.Date).FirstOrDefault();

                MacdResult result = new MacdResult
                {
                    Index = (int)h.Index,
                    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,
                        Index = h.Index - slowPeriod,
                        Value = macd
                    };

                    emaDiff.Add(diff);
                }

                results.Add(result);
            }

            IEnumerable <EmaResult> emaSignal = CalcEma(emaDiff, signalPeriod);
            decimal?prevMacd   = null;
            decimal?prevSignal = null;


            // add signal, histogram to result
            foreach (MacdResult r in results)
            {
                EmaResult ds = emaSignal.Where(x => x.Date == r.Date).FirstOrDefault();

                if (ds?.Ema == null)
                {
                    continue;
                }

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

                // trend and divergence
                if (prevMacd != null && prevSignal != null)
                {
                    r.IsBullish   = (r.Macd > r.Signal);
                    r.IsDiverging = (Math.Abs((decimal)r.Macd - (decimal)r.Signal)
                                     > Math.Abs((decimal)prevMacd - (decimal)prevSignal));
                }

                // store for next iteration
                prevMacd   = r.Macd;
                prevSignal = r.Signal;
            }

            return(results);
        }
Exemple #16
0
        // TRIPLE EMA OSCILLATOR (TRIX)
        /// <include file='./info.xml' path='indicator/*' />
        ///
        public static IEnumerable <TrixResult> GetTrix <TQuote>(
            this IEnumerable <TQuote> history,
            int lookbackPeriod,
            int?signalPeriod = null)
            where TQuote : IQuote
        {
            // convert history to basic format
            List <BasicData> bdList = history.ConvertToBasic("C");

            // check parameter arguments
            ValidateTrix(bdList, lookbackPeriod);

            // initialize
            List <TrixResult> results = new(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()
                {
                    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 is not null and not 0)
                    {
                        result.Trix = 100 * (e3.Ema - lastEma) / lastEma;
                    }

                    lastEma = e3.Ema;

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

            return(results);
        }
Exemple #17
0
        // PRICE VOLUME OSCILLATOR (PVO)
        public static IEnumerable <PvoResult> GetPvo <TQuote>(
            IEnumerable <TQuote> history,
            int fastPeriod   = 12,
            int slowPeriod   = 26,
            int signalPeriod = 9)
            where TQuote : IQuote
        {
            // convert history to basic format
            List <BasicData> bdList = history.ConvertToBasic("V");

            // check parameter arguments
            ValidatePvo(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 <PvoResult> results = new List <PvoResult>(size);

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

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

                if (df?.Ema != null && ds?.Ema != null)
                {
                    decimal?pvo = (ds.Ema != 0) ?
                                  100 * (df.Ema - ds.Ema) / ds.Ema : null;

                    result.Pvo = pvo;

                    // temp data for interim EMA of PVO
                    BasicData diff = new BasicData
                    {
                        Date  = h.Date,
                        Value = (decimal)pvo
                    };

                    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++)
            {
                PvoResult r  = results[d];
                EmaResult ds = emaSignal[d + 1 - slowPeriod];

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

            return(results);
        }
Exemple #18
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);
        }
Exemple #19
0
        // MOVING AVERAGE CONVERGENCE/DIVERGENCE (MACD) OSCILLATOR
        public static IEnumerable <MacdResult> GetMacd(IEnumerable <Quote> history, int fastPeriod = 12, int slowPeriod = 26, int signalPeriod = 9)
        {
            // clean quotes
            history = Cleaners.PrepareHistory(history);

            // check for exceptions
            if (slowPeriod <= fastPeriod)
            {
                throw new BadParameterException("Fast period must be smaller than the slow period.");
            }

            int qtyHistory = history.Count();
            int minHistory = 2 * slowPeriod + signalPeriod;

            if (qtyHistory < minHistory)
            {
                throw new BadHistoryException("Insufficient history provided for MACD.  " +
                                              string.Format("You provided {0} periods of history when {1} is required.  "
                                                            + "Since this uses a smoothing technique, "
                                                            + "we recommend you use at least 250 data points prior to the intended "
                                                            + "usage date for maximum precision.", qtyHistory, minHistory));
            }

            // initialize
            IEnumerable <EmaResult> emaFast = GetEma(history, fastPeriod);
            IEnumerable <EmaResult> emaSlow = GetEma(history, slowPeriod);

            List <Quote>      emaDiff = new List <Quote>();
            List <MacdResult> results = new List <MacdResult>();

            foreach (Quote h in history)
            {
                EmaResult df = emaFast.Where(x => x.Date == h.Date).FirstOrDefault();
                EmaResult ds = emaSlow.Where(x => x.Date == h.Date).FirstOrDefault();

                MacdResult result = new MacdResult
                {
                    Index = (int)h.Index,
                    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
                    Quote diff = new Quote
                    {
                        Date  = h.Date,
                        Index = h.Index - slowPeriod,
                        Close = macd
                    };

                    emaDiff.Add(diff);
                }

                results.Add(result);
            }

            IEnumerable <EmaResult> emaSignal = GetEma(emaDiff, signalPeriod);
            decimal?prevMacd   = null;
            decimal?prevSignal = null;


            // add signal, histogram to result
            foreach (MacdResult r in results)
            {
                EmaResult ds = emaSignal.Where(x => x.Date == r.Date).FirstOrDefault();

                if (ds?.Ema == null)
                {
                    continue;
                }

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

                // trend and divergence
                if (prevMacd != null && prevSignal != null)
                {
                    r.IsBullish   = (r.Macd > r.Signal) ? true : false;
                    r.IsDiverging = (Math.Abs((decimal)r.Macd - (decimal)r.Signal) > Math.Abs((decimal)prevMacd - (decimal)prevSignal)) ? true : false;
                }

                // store for next iteration
                prevMacd   = r.Macd;
                prevSignal = r.Signal;
            }

            return(results);
        }
Exemple #20
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> 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 {
                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
                    if (signalPeriod != null && index >= 3 * lookbackPeriod - 2 + signalPeriod)
                    {
                        decimal sumSma = 0m;
                        for (int p = index - (int)signalPeriod; p < index; p++)
                        {
                            sumSma += (decimal)results[p].Trix;
                        }

                        result.Signal = sumSma / signalPeriod;
                    }
                }
            }

            return(results);
        }
Exemple #21
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
        {
            // clean quotes
            List <TQuote> historyList = history.Sort();

            // check parameters
            ValidateMacd(history, fastPeriod, slowPeriod, signalPeriod);

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

            List <BasicData>  emaDiff = new List <BasicData>();
            List <MacdResult> results = new List <MacdResult>();

            for (int i = 0; i < historyList.Count; i++)
            {
                TQuote    h  = historyList[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 < results.Count; d++)
            {
                MacdResult r  = results[d];
                EmaResult  ds = emaSignal[d + 1 - slowPeriod];

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

            return(results);
        }