예제 #1
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");

            // 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);
        }
예제 #2
0
        // MOVING AVERAGE CONVERGENCE/DIVERGENCE (MACD) OSCILLATOR
        public static IEnumerable <MacdResult> GetMacd(IEnumerable <Quote> history, int fastPeriod = 12, int slowPeriod = 26, int signalPeriod = 9)
        {
            // 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);
        }