Ejemplo n.º 1
0
    // TRIPLE EXPONENTIAL MOVING AVERAGE
    /// <include file='./info.xml' path='indicator/*' />
    ///
    public static IEnumerable <TemaResult> GetTripleEma <TQuote>(
        this IEnumerable <TQuote> quotes,
        int lookbackPeriods)
        where TQuote : IQuote
    {
        // convert quotes
        List <BasicD> bdList = quotes.ConvertToBasic(CandlePart.Close);

        // check parameter arguments
        ValidateTema(lookbackPeriods);

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

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

        List <EmaResult> emaN2 = CalcEma(bd2, lookbackPeriods);

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

        List <EmaResult> emaN3 = CalcEma(bd3, lookbackPeriods);

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

            TemaResult result = new()
            {
                Date = e1.Date
            };

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

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

            results.Add(result);
        }

        return(results);
    }
Ejemplo n.º 2
0
        public void Convergence()
        {
            foreach (int qty in convergeQuantities)
            {
                IEnumerable <Quote>     h = HistoryTestData.GetLong(115 + qty);
                IEnumerable <EmaResult> r = Indicator.GetEma(h, 15);

                EmaResult l = r.LastOrDefault();
                Console.WriteLine("EMA on {0:d} with {1,4} periods: {2:N8}",
                                  l.Date, h.Count(), l.Ema);
            }
        }
Ejemplo n.º 3
0
    public void Find()
    {
        IEnumerable <Quote>     quotes     = TestData.GetDefault();
        IEnumerable <EmaResult> emaResults = Indicator.GetEma(quotes, 20);

        // find specific date
        DateTime findDate = DateTime.ParseExact("2018-12-31", "yyyy-MM-dd", EnglishCulture);

        EmaResult r = emaResults.Find(findDate);

        Assert.AreEqual(249.3519m, Math.Round((decimal)r.Ema, 4));
    }
Ejemplo n.º 4
0
    public void Ema()
    {
        foreach (int qty in QuotesQuantities)
        {
            IEnumerable <Quote>     quotes = TestData.GetLongish(qty);
            IEnumerable <EmaResult> r      = quotes.GetEma(15);

            EmaResult l = r.LastOrDefault();
            Console.WriteLine(
                "EMA(15) on {0:d} with {1,4} periods: {2:N8}",
                l.Date, quotes.Count(), l.Ema);
        }
    }
Ejemplo n.º 5
0
    public void Removed()
    {
        List <EmaResult> results = quotes.GetEma(20)
                                   .RemoveWarmupPeriods()
                                   .ToList();

        // assertions
        Assert.AreEqual(502 - (20 + 100), results.Count);

        EmaResult last = results.LastOrDefault();

        Assert.AreEqual(249.3519m, Math.Round((decimal)last.Ema, 4));
    }
Ejemplo n.º 6
0
    // KELTNER CHANNELS
    /// <include file='./info.xml' path='indicator/*' />
    ///
    public static IEnumerable <KeltnerResult> GetKeltner <TQuote>(
        this IEnumerable <TQuote> quotes,
        int emaPeriods     = 20,
        decimal multiplier = 2,
        int atrPeriods     = 10)
        where TQuote : IQuote
    {
        // sort quotes
        List <TQuote> quotesList = quotes.SortToList();

        // check parameter arguments
        ValidateKeltner(emaPeriods, multiplier, atrPeriods);

        // initialize
        List <KeltnerResult> results    = new(quotesList.Count);
        List <EmaResult>     emaResults = GetEma(quotes, emaPeriods).ToList();
        List <AtrResult>     atrResults = GetAtr(quotes, atrPeriods).ToList();
        int lookbackPeriods             = Math.Max(emaPeriods, atrPeriods);

        // roll through quotes
        for (int i = 0; i < quotesList.Count; i++)
        {
            TQuote q     = quotesList[i];
            int    index = i + 1;

            KeltnerResult result = new()
            {
                Date = q.Date
            };

            if (index >= lookbackPeriods)
            {
                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);
    }
Ejemplo n.º 7
0
        public void GetEmaTest()
        {
            int lookbackPeriod = 20;
            IEnumerable <EmaResult> results = Indicator.GetEma(history, lookbackPeriod);

            // assertions

            // proper quantities
            // should always be the same number of results as there is history
            Assert.AreEqual(502, results.Count());
            Assert.AreEqual(502 - lookbackPeriod + 1, results.Where(x => x.Ema != null).Count());

            // sample value
            EmaResult ema = results.Where(x => x.Date == DateTime.Parse("12/31/2018")).FirstOrDefault();

            Assert.AreEqual((decimal)249.3519, Math.Round((decimal)ema.Ema, 4));
        }
Ejemplo n.º 8
0
        public void GetDoubleEmaTest()
        {
            int lookbackPeriod = 20;
            IEnumerable <EmaResult> results = Indicator.GetDoubleEma(history, lookbackPeriod);

            // assertions

            // proper quantities
            // should always be the same number of results as there is history
            Assert.AreEqual(502, results.Count());
            Assert.AreEqual(502 - 2 * lookbackPeriod + 1, results.Where(x => x.Ema != null).Count());

            // sample value
            EmaResult r = results.Where(x => x.Index == 502).FirstOrDefault();

            Assert.AreEqual(241.1677m, Math.Round((decimal)r.Ema, 4));
        }
Ejemplo n.º 9
0
    // DOUBLE EXPONENTIAL MOVING AVERAGE
    /// <include file='./info.xml' path='indicator/*' />
    ///
    public static IEnumerable <DemaResult> GetDoubleEma <TQuote>(
        this IEnumerable <TQuote> quotes,
        int lookbackPeriods)
        where TQuote : IQuote
    {
        // convert quotes
        List <BasicD> bdList = quotes.ConvertToBasic(CandlePart.Close);

        // check parameter arguments
        ValidateDema(lookbackPeriods);

        // initialize
        List <DemaResult> results = new(bdList.Count);
        List <EmaResult>  emaN    = CalcEma(bdList, lookbackPeriods);

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

        List <EmaResult> emaN2 = CalcEma(bd2, lookbackPeriods);

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

            DemaResult result = new()
            {
                Date = e1.Date
            };

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

            results.Add(result);
        }

        return(results);
    }
Ejemplo n.º 10
0
    // CHAIKIN OSCILLATOR
    /// <include file='./info.xml' path='indicator/*' />
    ///
    public static IEnumerable <ChaikinOscResult> GetChaikinOsc <TQuote>(
        this IEnumerable <TQuote> quotes,
        int fastPeriods = 3,
        int slowPeriods = 10)
        where TQuote : IQuote
    {
        // check parameter arguments
        ValidateChaikinOsc(fastPeriods, slowPeriods);

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

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

        List <EmaResult> adlEmaSlow = CalcEma(bdAdl, slowPeriods);
        List <EmaResult> adlEmaFast = CalcEma(bdAdl, fastPeriods);

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

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

            r.Oscillator = (double)(f.Ema - s.Ema);
        }

        return(results);
    }
Ejemplo n.º 11
0
        public void CustomQuoteClass()
        {
            List <MyGenericQuote> myGenericHistory = HistoryTestData.Get()
                                                     .Select(x => new MyGenericQuote
            {
                CloseDate       = x.Date,
                Open            = x.Open,
                High            = x.High,
                Low             = x.Low,
                CloseValue      = x.Close,
                Volume          = x.Volume,
                MyOtherProperty = 123456
            })
                                                     .ToList();

            List <EmaResult> results = Indicator.GetEma(myGenericHistory, 20)
                                       .ToList();

            // assertions

            // proper quantities
            // should always be the same number of results as there is history
            Assert.AreEqual(502, results.Count);
            Assert.AreEqual(483, results.Where(x => x.Ema != null).Count());

            // sample values
            EmaResult r1 = results[501];

            Assert.AreEqual(249.3519m, Math.Round((decimal)r1.Ema, 4));

            EmaResult r2 = results[249];

            Assert.AreEqual(255.3873m, Math.Round((decimal)r2.Ema, 4));

            EmaResult r3 = results[29];

            Assert.AreEqual(216.6228m, Math.Round((decimal)r3.Ema, 4));
        }
Ejemplo n.º 12
0
    // PRICE VOLUME OSCILLATOR (PVO)
    /// <include file='./info.xml' path='indicator/*' />
    ///
    public static IEnumerable <PvoResult> GetPvo <TQuote>(
        this IEnumerable <TQuote> quotes,
        int fastPeriods   = 12,
        int slowPeriods   = 26,
        int signalPeriods = 9)
        where TQuote : IQuote
    {
        // convert quotes
        List <BasicD> bdList = quotes.ConvertToBasic(CandlePart.Volume);

        // check parameter arguments
        ValidatePvo(fastPeriods, slowPeriods, signalPeriods);

        // initialize
        List <EmaResult> emaFast = CalcEma(bdList, fastPeriods);
        List <EmaResult> emaSlow = CalcEma(bdList, slowPeriods);

        int              length  = bdList.Count;
        List <BasicD>    emaDiff = new();
        List <PvoResult> results = new(length);

        // roll through quotes
        for (int i = 0; i < length; i++)
        {
            BasicD    h  = bdList[i];
            EmaResult df = emaFast[i];
            EmaResult ds = emaSlow[i];

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

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

                result.Pvo = (decimal?)pvo;

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

                emaDiff.Add(diff);
            }

            results.Add(result);
        }

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

        for (int d = slowPeriods - 1; d < length; d++)
        {
            PvoResult r  = results[d];
            EmaResult ds = emaSignal[d + 1 - slowPeriods];

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

        return(results);
    }
Ejemplo n.º 13
0
    // TRIPLE EMA OSCILLATOR (TRIX)
    /// <include file='./info.xml' path='indicator/*' />
    ///
    public static IEnumerable <TrixResult> GetTrix <TQuote>(
        this IEnumerable <TQuote> quotes,
        int lookbackPeriods,
        int?signalPeriods = null)
        where TQuote : IQuote
    {
        // convert quotes
        List <BasicD> bdList = quotes.ConvertToBasic(CandlePart.Close);

        // check parameter arguments
        ValidateTrix(lookbackPeriods);

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

        List <EmaResult> emaN1 = CalcEma(bdList, lookbackPeriods);

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

        List <EmaResult> emaN2 = CalcEma(bd2, lookbackPeriods);

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

        List <EmaResult> emaN3 = CalcEma(bd3, lookbackPeriods);

        // 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 * lookbackPeriods) - 2)
            {
                EmaResult e2 = emaN2[index - lookbackPeriods];
                EmaResult e3 = emaN3[index - (2 * lookbackPeriods) + 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(signalPeriods, index, lookbackPeriods, results);
            }
        }

        return(results);
    }
Ejemplo n.º 14
0
    // MOVING AVERAGE CONVERGENCE/DIVERGENCE (MACD) OSCILLATOR
    /// <include file='./info.xml' path='indicator/*' />
    ///
    public static IEnumerable <MacdResult> GetMacd <TQuote>(
        this IEnumerable <TQuote> quotes,
        int fastPeriods   = 12,
        int slowPeriods   = 26,
        int signalPeriods = 9)
        where TQuote : IQuote
    {
        // convert quotes
        List <BasicD> bdList = quotes.ConvertToBasic(CandlePart.Close);

        // check parameter arguments
        ValidateMacd(fastPeriods, slowPeriods, signalPeriods);

        // initialize
        List <EmaResult> emaFast = CalcEma(bdList, fastPeriods);
        List <EmaResult> emaSlow = CalcEma(bdList, slowPeriods);

        int               length  = bdList.Count;
        List <BasicD>     emaDiff = new();
        List <MacdResult> results = new(length);

        // roll through quotes
        for (int i = 0; i < length; i++)
        {
            BasicD    h  = bdList[i];
            EmaResult df = emaFast[i];
            EmaResult ds = emaSlow[i];

            MacdResult result = new()
            {
                Date    = h.Date,
                FastEma = df.Ema,
                SlowEma = ds.Ema
            };

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

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

                emaDiff.Add(diff);
            }

            results.Add(result);
        }

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

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

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

        return(results);
    }