public void Convergence() { foreach (int qty in convergeQuantities) { IEnumerable <Quote> h = HistoryTestData.GetLong(130 + qty); IEnumerable <PvoResult> r = Indicator.GetPvo(h); PvoResult l = r.LastOrDefault(); Console.WriteLine("PVO on {0:d} with {1,4} periods: {2:N8}", l.Date, h.Count(), l.Pvo); } }
public void Pvo() { foreach (int qty in QuotesQuantities) { IEnumerable <Quote> quotes = TestData.GetLongish(qty); IEnumerable <PvoResult> r = quotes.GetPvo(); PvoResult l = r.LastOrDefault(); Console.WriteLine( "PVO on {0:d} with {1,4} periods: {2:N8}", l.Date, quotes.Count(), l.Pvo); } }
public void Standard() { int fastPeriod = 12; int slowPeriod = 26; int signalPeriod = 9; List <PvoResult> results = history.GetPvo(fastPeriod, slowPeriod, signalPeriod) .ToList(); // assertions // proper quantities // should always be the same number of results as there is history Assert.AreEqual(502, results.Count); Assert.AreEqual(477, results.Where(x => x.Pvo != null).Count()); Assert.AreEqual(469, results.Where(x => x.Signal != null).Count()); Assert.AreEqual(469, results.Where(x => x.Histogram != null).Count()); // sample values PvoResult r1 = results[24]; Assert.AreEqual(null, r1.Pvo); Assert.AreEqual(null, r1.Signal); Assert.AreEqual(null, r1.Histogram); PvoResult r2 = results[33]; Assert.AreEqual(1.5795m, Math.Round((decimal)r2.Pvo, 4)); Assert.AreEqual(-3.5530m, Math.Round((decimal)r2.Signal, 4)); Assert.AreEqual(5.1325m, Math.Round((decimal)r2.Histogram, 4)); PvoResult r3 = results[149]; Assert.AreEqual(-7.1910m, Math.Round((decimal)r3.Pvo, 4)); Assert.AreEqual(-5.1159m, Math.Round((decimal)r3.Signal, 4)); Assert.AreEqual(-2.0751m, Math.Round((decimal)r3.Histogram, 4)); PvoResult r4 = results[249]; Assert.AreEqual(-6.3667m, Math.Round((decimal)r4.Pvo, 4)); Assert.AreEqual(1.7333m, Math.Round((decimal)r4.Signal, 4)); Assert.AreEqual(-8.1000m, Math.Round((decimal)r4.Histogram, 4)); PvoResult r5 = results[501]; Assert.AreEqual(10.4395m, Math.Round((decimal)r5.Pvo, 4)); Assert.AreEqual(12.2681m, Math.Round((decimal)r5.Signal, 4)); Assert.AreEqual(-1.8286m, Math.Round((decimal)r5.Histogram, 4)); }
public void Removed() { int fastPeriods = 12; int slowPeriods = 26; int signalPeriods = 9; List <PvoResult> results = quotes.GetPvo(fastPeriods, slowPeriods, signalPeriods) .RemoveWarmupPeriods() .ToList(); // assertions Assert.AreEqual(502 - (slowPeriods + signalPeriods + 250), results.Count); PvoResult last = results.LastOrDefault(); Assert.AreEqual(10.4395m, Math.Round((decimal)last.Pvo, 4)); Assert.AreEqual(12.2681m, Math.Round((decimal)last.Signal, 4)); Assert.AreEqual(-1.8286m, Math.Round((decimal)last.Histogram, 4)); }
// 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); }