Example #1
0
        private static List <StochResult> SmoothOscillator(
            List <StochResult> results, int lookbackPeriod, int smoothPeriod)
        {
            // temporarily store interim smoothed oscillator
            int smoothIndex = lookbackPeriod + smoothPeriod - 2;

            for (int i = smoothIndex; i < results.Count; i++)
            {
                StochResult r     = results[i];
                int         index = i + 1;

                decimal sumOsc = 0m;
                for (int p = index - smoothPeriod; p < index; p++)
                {
                    StochResult d = results[p];
                    sumOsc += (decimal)d.Oscillator;
                }

                r.Smooth = sumOsc / smoothPeriod;
            }

            // replace oscillator
            foreach (StochResult r in results)
            {
                r.Oscillator = (r.Smooth != null) ? r.Smooth : null;
            }

            return(results);
        }
Example #2
0
        // STOCHASTIC RSI
        public static IEnumerable <StochRsiResult> GetStochRsi <TQuote>(
            IEnumerable <TQuote> history,
            int rsiPeriod,
            int stochPeriod,
            int signalPeriod,
            int smoothPeriod = 1)
            where TQuote : IQuote
        {
            // validate parameters
            ValidateStochRsi(history, rsiPeriod, stochPeriod, signalPeriod, smoothPeriod);

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

            // get RSI
            List <RsiResult> rsiResults = GetRsi(history, rsiPeriod).ToList();

            // convert rsi to quote format
            List <Quote> rsiQuotes = rsiResults
                                     .Where(x => x.Rsi != null)
                                     .Select(x => new Quote
            {
                Date  = x.Date,
                High  = (decimal)x.Rsi,
                Low   = (decimal)x.Rsi,
                Close = (decimal)x.Rsi
            })
                                     .ToList();

            // get Stochastic of RSI
            List <StochResult> stoResults = GetStoch(rsiQuotes, stochPeriod, signalPeriod, smoothPeriod).ToList();

            // compose
            for (int i = 0; i < rsiResults.Count; i++)
            {
                RsiResult r     = rsiResults[i];
                int       index = i + 1;

                StochRsiResult result = new StochRsiResult
                {
                    Date = r.Date
                };

                if (index >= rsiPeriod + stochPeriod)
                {
                    StochResult sto = stoResults[index - rsiPeriod - 1];

                    result.StochRsi = sto.Oscillator;
                    result.Signal   = sto.Signal;
                }

                results.Add(result);
            }

            return(results);
        }
Example #3
0
        // STOCHASTIC RSI
        public static IEnumerable <StochRsiResult> GetStochRsi(IEnumerable <Quote> history,
                                                               int rsiPeriod, int stochPeriod, int signalPeriod, int smoothPeriod = 1)
        {
            // clean quotes
            history = Cleaners.PrepareHistory(history);

            // validate parameters
            ValidateStochRsi(history, rsiPeriod, stochPeriod, signalPeriod, smoothPeriod);

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

            // get RSI
            IEnumerable <RsiResult> rsiResults = GetRsi(history, rsiPeriod);

            // convert rsi to quote format
            List <Quote> rsiQuotes = rsiResults
                                     .Where(x => x.Rsi != null)
                                     .Select(x => new Quote
            {
                Index = null,
                Date  = x.Date,
                High  = (decimal)x.Rsi,
                Low   = (decimal)x.Rsi,
                Close = (decimal)x.Rsi
            })
                                     .ToList();

            // get Stochastic of RSI
            IEnumerable <StochResult> stoResults = GetStoch(rsiQuotes, stochPeriod, signalPeriod, smoothPeriod);

            // compose
            foreach (RsiResult r in rsiResults)
            {
                StochRsiResult result = new StochRsiResult
                {
                    Index = r.Index,
                    Date  = r.Date
                };

                if (r.Index >= rsiPeriod + stochPeriod)
                {
                    StochResult sto = stoResults
                                      .Where(x => x.Index == r.Index - stochPeriod)
                                      .FirstOrDefault();

                    result.StochRsi     = sto.Oscillator;
                    result.Signal       = sto.Signal;
                    result.IsIncreasing = sto.IsIncreasing;
                }

                results.Add(result);
            }

            return(results);
        }
Example #4
0
        // STOCHASTIC OSCILLATOR
        public static IEnumerable <StochResult> GetStoch(IEnumerable <Quote> history, int lookbackPeriod = 14, int signalPeriod = 3, int smoothPeriod = 3)
        {
            // clean quotes
            history = Cleaners.PrepareHistory(history);

            // validate parameters
            ValidateStoch(history, lookbackPeriod, signalPeriod, smoothPeriod);

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

            // oscillator
            foreach (Quote h in history)
            {
                StochResult result = new StochResult
                {
                    Index = (int)h.Index,
                    Date  = h.Date
                };

                if (h.Index >= lookbackPeriod)
                {
                    decimal lowLow = history.Where(x => x.Index > (h.Index - lookbackPeriod) && x.Index <= h.Index)
                                     .Select(v => v.Low)
                                     .Min();

                    decimal highHigh = history.Where(x => x.Index > (h.Index - lookbackPeriod) && x.Index <= h.Index)
                                       .Select(v => v.High)
                                       .Max();

                    if (lowLow != highHigh)
                    {
                        result.Oscillator = 100 * (float)((h.Close - lowLow) / (highHigh - lowLow));
                    }
                    else
                    {
                        result.Oscillator = 0;
                    }
                }
                results.Add(result);
            }


            // smooth the oscillator
            if (smoothPeriod > 1)
            {
                // temporarily store interim smoothed oscillator
                foreach (StochResult r in results.Where(x => x.Index >= (lookbackPeriod + smoothPeriod)))
                {
                    r.Smooth = results.Where(x => x.Index > (r.Index - smoothPeriod) && x.Index <= r.Index)
                               .Select(v => v.Oscillator)
                               .Average();
                }

                // replace oscillator
                foreach (StochResult r in results)
                {
                    if (r.Smooth != null)
                    {
                        r.Oscillator = (float)r.Smooth;
                    }
                    else
                    {
                        r.Oscillator = null;  // erase unsmoothed
                    }
                }
            }


            // new signal and trend info
            float lastOsc          = 0;
            bool? lastIsIncreasing = null;

            foreach (StochResult r in results
                     .Where(x => x.Index >= (lookbackPeriod + signalPeriod + smoothPeriod) && x.Oscillator != null))
            {
                r.Signal = results.Where(x => x.Index > (r.Index - signalPeriod) && x.Index <= r.Index)
                           .Select(v => v.Oscillator)
                           .Average();

                if (r.Index >= (lookbackPeriod + signalPeriod + smoothPeriod) + 1)
                {
                    if (r.Oscillator > lastOsc)
                    {
                        r.IsIncreasing = true;
                    }
                    else if (r.Oscillator < lastOsc)
                    {
                        r.IsIncreasing = false;
                    }
                    else
                    {
                        // no change, keep trend
                        r.IsIncreasing = lastIsIncreasing;
                    }
                }

                lastOsc          = (float)r.Oscillator;
                lastIsIncreasing = r.IsIncreasing;
            }

            return(results);
        }
Example #5
0
        // STOCHASTIC OSCILLATOR
        /// <include file='./info.xml' path='indicator/*' />
        ///
        public static IEnumerable <StochResult> GetStoch <TQuote>(
            IEnumerable <TQuote> history,
            int lookbackPeriod = 14,
            int signalPeriod   = 3,
            int smoothPeriod   = 3)
            where TQuote : IQuote
        {
            // sort history
            List <TQuote> historyList = history.Sort();

            // check parameter arguments
            ValidateStoch(history, lookbackPeriod, signalPeriod, smoothPeriod);

            // initialize
            int size = historyList.Count;
            List <StochResult> results = new(size);

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

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

                if (index >= lookbackPeriod)
                {
                    decimal highHigh = 0;
                    decimal lowLow   = decimal.MaxValue;

                    for (int p = index - lookbackPeriod; p < index; p++)
                    {
                        TQuote d = historyList[p];

                        if (d.High > highHigh)
                        {
                            highHigh = d.High;
                        }

                        if (d.Low < lowLow)
                        {
                            lowLow = d.Low;
                        }
                    }

                    result.Oscillator = lowLow != highHigh
                        ? 100 * ((h.Close - lowLow) / (highHigh - lowLow))
                        : 0;
                }
                results.Add(result);
            }


            // smooth the oscillator
            if (smoothPeriod > 1)
            {
                results = SmoothOscillator(results, size, lookbackPeriod, smoothPeriod);
            }


            // signal (%D) and %J
            int stochIndex = lookbackPeriod + smoothPeriod - 2;

            for (int i = stochIndex; i < size; i++)
            {
                StochResult r     = results[i];
                int         index = i + 1;

                // add signal
                int signalIndex = lookbackPeriod + smoothPeriod + signalPeriod - 2;

                if (signalPeriod <= 1)
                {
                    r.Signal = r.Oscillator;
                }
                else if (index >= signalIndex)
                {
                    decimal sumOsc = 0m;
                    for (int p = index - signalPeriod; p < index; p++)
                    {
                        StochResult d = results[p];
                        sumOsc += (decimal)d.Oscillator;
                    }

                    r.Signal   = sumOsc / signalPeriod;
                    r.PercentJ = (3 * r.Oscillator) - (2 * r.Signal);
                }
            }

            return(results);
        }
Example #6
0
        // STOCHASTIC OSCILLATOR
        public static IEnumerable <StochResult> GetStoch(IEnumerable <Quote> history, int lookbackPeriod = 14, int signalPeriod = 3, int smoothPeriod = 3)
        {
            // clean quotes
            history = Cleaners.PrepareHistory(history);

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

            if (qtyHistory < minHistory)
            {
                throw new BadHistoryException("Insufficient history provided for Stochastic.  " +
                                              string.Format("You provided {0} periods of history when {1} is required.", qtyHistory, minHistory));
            }

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

            // oscillator
            foreach (Quote h in history)
            {
                StochResult result = new StochResult
                {
                    Index = (int)h.Index,
                    Date  = h.Date
                };

                if (h.Index >= lookbackPeriod)
                {
                    decimal lowLow = history.Where(x => x.Index > (h.Index - lookbackPeriod) && x.Index <= h.Index)
                                     .Select(v => v.Low)
                                     .Min();

                    decimal highHigh = history.Where(x => x.Index > (h.Index - lookbackPeriod) && x.Index <= h.Index)
                                       .Select(v => v.High)
                                       .Max();

                    if (lowLow != highHigh)
                    {
                        result.Oscillator = 100 * (float)((h.Close - lowLow) / (highHigh - lowLow));
                    }
                    else
                    {
                        result.Oscillator = 0;
                    }
                }
                results.Add(result);
            }


            // smooth the oscillator
            if (smoothPeriod > 1)
            {
                // temporarily store interim smoothed oscillator
                foreach (StochResult r in results.Where(x => x.Index >= (lookbackPeriod + smoothPeriod)))
                {
                    r.Smooth = results.Where(x => x.Index > (r.Index - smoothPeriod) && x.Index <= r.Index)
                               .Select(v => v.Oscillator)
                               .Average();
                }

                // replace oscillator
                foreach (StochResult r in results)
                {
                    if (r.Smooth != null)
                    {
                        r.Oscillator = (float)r.Smooth;
                    }
                    else
                    {
                        r.Oscillator = null;  // erase unsmoothed
                    }
                }
            }


            // new signal and trend info
            float lastOsc = 0;

            foreach (StochResult r in results
                     .Where(x => x.Index >= (lookbackPeriod + signalPeriod + smoothPeriod) && x.Oscillator != null))
            {
                r.Signal = results.Where(x => x.Index > (r.Index - signalPeriod) && x.Index <= r.Index)
                           .Select(v => v.Oscillator)
                           .Average();

                r.IsIncreasing = (r.Oscillator >= lastOsc) ? true : false;
                lastOsc        = (float)r.Oscillator;
            }

            return(results);
        }
Example #7
0
        // STOCHASTIC OSCILLATOR
        public static IEnumerable <StochResult> GetStoch <TQuote>(
            IEnumerable <TQuote> history,
            int lookbackPeriod = 14,
            int signalPeriod   = 3,
            int smoothPeriod   = 3)
            where TQuote : IQuote
        {
            // clean quotes
            List <TQuote> historyList = history.Sort();

            // validate parameters
            ValidateStoch(history, lookbackPeriod, signalPeriod, smoothPeriod);

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

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

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

                if (index >= lookbackPeriod)
                {
                    decimal highHigh = 0;
                    decimal lowLow   = decimal.MaxValue;

                    for (int p = index - lookbackPeriod; p < index; p++)
                    {
                        TQuote d = historyList[p];

                        if (d.High > highHigh)
                        {
                            highHigh = d.High;
                        }

                        if (d.Low < lowLow)
                        {
                            lowLow = d.Low;
                        }
                    }

                    if (lowLow != highHigh)
                    {
                        result.Oscillator = 100 * ((h.Close - lowLow) / (highHigh - lowLow));
                    }
                    else
                    {
                        result.Oscillator = 0;
                    }
                }
                results.Add(result);
            }


            // smooth the oscillator
            if (smoothPeriod > 1)
            {
                results = SmoothOscillator(results, lookbackPeriod, smoothPeriod);
            }


            // signal and period direction info
            int stochIndex = lookbackPeriod + smoothPeriod - 2;

            for (int i = stochIndex; i < results.Count; i++)
            {
                StochResult r     = results[i];
                int         index = i + 1;

                // add signal
                int signalIndex = lookbackPeriod + smoothPeriod + signalPeriod - 2;

                if (signalPeriod <= 1)
                {
                    r.Signal = r.Oscillator;
                }
                else if (index >= signalIndex)
                {
                    decimal sumOsc = 0m;
                    for (int p = index - signalPeriod; p < index; p++)
                    {
                        StochResult d = results[p];
                        sumOsc += (decimal)d.Oscillator;
                    }

                    r.Signal = sumOsc / signalPeriod;
                }
            }

            return(results);
        }
Example #8
0
        // STOCHASTIC OSCILLATOR
        public static IEnumerable <StochResult> GetStoch(IEnumerable <Quote> history, int lookbackPeriod = 14, int signalPeriod = 3, int smoothPeriod = 3)
        {
            // clean quotes
            List <Quote> historyList = Cleaners.PrepareHistory(history).ToList();

            // validate parameters
            ValidateStoch(history, lookbackPeriod, signalPeriod, smoothPeriod);

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

            // oscillator
            for (int i = 0; i < historyList.Count; i++)
            {
                Quote h = historyList[i];

                StochResult result = new StochResult
                {
                    Index = (int)h.Index,
                    Date  = h.Date
                };

                if (h.Index >= lookbackPeriod)
                {
                    decimal highHigh = 0;
                    decimal lowLow   = decimal.MaxValue;

                    for (int p = (int)h.Index - lookbackPeriod; p < h.Index; p++)
                    {
                        Quote d = historyList[p];

                        if (d.High > highHigh)
                        {
                            highHigh = d.High;
                        }

                        if (d.Low < lowLow)
                        {
                            lowLow = d.Low;
                        }
                    }

                    if (lowLow != highHigh)
                    {
                        result.Oscillator = 100 * ((h.Close - lowLow) / (highHigh - lowLow));
                    }
                    else
                    {
                        result.Oscillator = 0;
                    }
                }
                results.Add(result);
            }


            // smooth the oscillator
            if (smoothPeriod > 1)
            {
                results = SmoothOscillator(results, lookbackPeriod, smoothPeriod);
            }


            // signal and period direction info
            int stochIndex = lookbackPeriod + smoothPeriod - 1;

            foreach (StochResult r in results.Where(x => x.Index >= stochIndex))
            {
                // add signal
                int signalIndex = lookbackPeriod + smoothPeriod + signalPeriod - 2;

                if (signalPeriod <= 1)
                {
                    r.Signal = r.Oscillator;
                }
                else if (r.Index >= signalIndex)
                {
                    decimal sumOsc = 0m;
                    for (int p = r.Index - signalPeriod; p < r.Index; p++)
                    {
                        StochResult d = results[p];
                        sumOsc += (decimal)d.Oscillator;
                    }

                    r.Signal = sumOsc / signalPeriod;
                }
            }

            return(results);
        }
Example #9
0
        // STOCHASTIC OSCILLATOR
        public static IEnumerable <StochResult> GetStoch(IEnumerable <Quote> history, int lookbackPeriod = 14, int signalPeriod = 3, int smoothPeriod = 3)
        {
            // clean quotes
            Cleaners.PrepareHistory(history);

            // validate parameters
            ValidateStoch(history, lookbackPeriod, signalPeriod, smoothPeriod);

            // initialize
            List <Quote>       historyList = history.ToList();
            List <StochResult> results     = new List <StochResult>();

            // oscillator
            for (int i = 0; i < historyList.Count; i++)
            {
                Quote h = historyList[i];

                StochResult result = new StochResult
                {
                    Index = (int)h.Index,
                    Date  = h.Date
                };

                if (h.Index >= lookbackPeriod)
                {
                    List <Quote> period = historyList
                                          .Where(x => x.Index > (h.Index - lookbackPeriod) && x.Index <= h.Index)
                                          .ToList();

                    decimal lowLow   = period.Select(v => v.Low).Min();
                    decimal highHigh = period.Select(v => v.High).Max();

                    if (lowLow != highHigh)
                    {
                        result.Oscillator = 100 * ((h.Close - lowLow) / (highHigh - lowLow));
                    }
                    else
                    {
                        result.Oscillator = 0;
                    }
                }
                results.Add(result);
            }


            // smooth the oscillator
            if (smoothPeriod > 1)
            {
                results = SmoothOscillator(results, lookbackPeriod, smoothPeriod);
            }


            // signal and period direction info
            int stochIndex = lookbackPeriod + smoothPeriod - 1;

            foreach (StochResult r in results.Where(x => x.Index >= stochIndex))
            {
                // add signal
                int signalIndex = lookbackPeriod + smoothPeriod + signalPeriod - 2;

                if (signalPeriod <= 1)
                {
                    r.Signal = r.Oscillator;
                }
                else if (r.Index >= signalIndex)
                {
                    r.Signal = results
                               .Where(x => x.Index > (r.Index - signalPeriod) && x.Index <= r.Index)
                               .ToList()
                               .Select(v => v.Oscillator)
                               .Average();
                }
            }

            return(results);
        }
Example #10
0
        // STOCHASTIC OSCILLATOR
        public static IEnumerable <StochResult> GetStoch(IEnumerable <Quote> history, int lookbackPeriod = 14, int signalPeriod = 3, int smoothPeriod = 3)
        {
            // clean quotes
            history = Cleaners.PrepareHistory(history);

            // validate parameters
            ValidateStoch(history, lookbackPeriod, signalPeriod, smoothPeriod);

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

            // oscillator
            foreach (Quote h in history)
            {
                StochResult result = new StochResult
                {
                    Index = (int)h.Index,
                    Date  = h.Date
                };

                if (h.Index >= lookbackPeriod)
                {
                    decimal lowLow = history.Where(x => x.Index > (h.Index - lookbackPeriod) && x.Index <= h.Index)
                                     .Select(v => v.Low)
                                     .Min();

                    decimal highHigh = history.Where(x => x.Index > (h.Index - lookbackPeriod) && x.Index <= h.Index)
                                       .Select(v => v.High)
                                       .Max();

                    if (lowLow != highHigh)
                    {
                        result.Oscillator = 100 * ((h.Close - lowLow) / (highHigh - lowLow));
                    }
                    else
                    {
                        result.Oscillator = 0;
                    }
                }
                results.Add(result);
            }


            // smooth the oscillator
            if (smoothPeriod > 1)
            {
                results = SmoothOscillator(results, lookbackPeriod, smoothPeriod);
            }


            // signal and period direction info
            decimal?lastOsc          = null;
            bool?   lastIsIncreasing = null;

            foreach (StochResult r in results
                     .Where(x => x.Index >= (lookbackPeriod + smoothPeriod - 1))
                     .OrderBy(x => x.Index))
            {
                // add signal
                if (r.Index >= lookbackPeriod + smoothPeriod + signalPeriod - 2)
                {
                    r.Signal = results.Where(x => x.Index > (r.Index - signalPeriod) && x.Index <= r.Index)
                               .Select(v => v.Oscillator)
                               .Average();
                }

                // add direction
                if (lastOsc != null)
                {
                    if (r.Oscillator > lastOsc)
                    {
                        r.IsIncreasing = true;
                    }
                    else if (r.Oscillator < lastOsc)
                    {
                        r.IsIncreasing = false;
                    }
                    else
                    {
                        // no change, keep trend
                        r.IsIncreasing = lastIsIncreasing;
                    }
                }

                lastOsc          = (decimal)r.Oscillator;
                lastIsIncreasing = r.IsIncreasing;
            }

            return(results);
        }