private static void CalcPmoSignal( List <PmoResult> results, int timePeriods, int smoothPeriods, int signalPeriods) { double signalConstant = 2d / (signalPeriods + 1); double?lastSignal = null; int startIndex = timePeriods + smoothPeriods + signalPeriods - 1; for (int i = startIndex - 1; i < results.Count; i++) { PmoResult pr = results[i]; int index = i + 1; if (index > startIndex) { pr.Signal = ((pr.Pmo - lastSignal) * signalConstant) + lastSignal; } else if (index == startIndex) { double?sumPmo = 0; for (int p = index - signalPeriods; p < index; p++) { PmoResult d = results[p]; sumPmo += d.Pmo; } pr.Signal = sumPmo / signalPeriods; } lastSignal = pr.Signal; } }
public void Convergence() { foreach (int qty in convergeQuantities) { IEnumerable <Quote> h = History.GetHistoryLong(130 + qty); IEnumerable <PmoResult> r = Indicator.GetPmo(h); PmoResult l = r.LastOrDefault(); Console.WriteLine("PMO on {0:d} with {1,4} periods: {2:N8}", l.Date, h.Count(), l.Pmo); } }
public void Pmo() { foreach (int qty in QuotesQuantities) { IEnumerable <Quote> quotes = TestData.GetLongish(qty); IEnumerable <PmoResult> r = quotes.GetPmo(); PmoResult l = r.LastOrDefault(); Console.WriteLine( "PMO on {0:d} with {1,4} periods: {2:N8}", l.Date, quotes.Count(), l.Pmo); } }
public void Removed() { List <PmoResult> results = quotes.GetPmo(35, 20, 10) .RemoveWarmupPeriods() .ToList(); // assertions Assert.AreEqual(502 - (35 + 20 + 250), results.Count); PmoResult last = results.LastOrDefault(); Assert.AreEqual(-2.7016, Math.Round((double)last.Pmo, 4)); Assert.AreEqual(-2.3117, Math.Round((double)last.Signal, 4)); }
// PRICE MOMENTUM OSCILLATOR (PMO) /// <include file='./info.xml' path='indicator/*' /> /// public static IEnumerable <PmoResult> GetPmo <TQuote>( this IEnumerable <TQuote> quotes, int timePeriods = 35, int smoothPeriods = 20, int signalPeriods = 10) where TQuote : IQuote { // check parameter arguments ValidatePmo(timePeriods, smoothPeriods, signalPeriods); // initialize List <PmoResult> results = CalcPmoRocEma(quotes, timePeriods); double smoothingConstant = 2d / smoothPeriods; double? lastPmo = null; // calculate PMO int startIndex = timePeriods + smoothPeriods; for (int i = startIndex - 1; i < results.Count; i++) { PmoResult pr = results[i]; int index = i + 1; if (index > startIndex) { pr.Pmo = ((pr.RocEma - lastPmo) * smoothingConstant) + lastPmo; } else if (index == startIndex) { double?sumRocEma = 0; for (int p = index - smoothPeriods; p < index; p++) { PmoResult d = results[p]; sumRocEma += d.RocEma; } pr.Pmo = sumRocEma / smoothPeriods; } lastPmo = pr.Pmo; } // add Signal CalcPmoSignal(results, timePeriods, smoothPeriods, signalPeriods); return(results); }
public void Standard() { List <PmoResult> results = quotes.GetPmo(35, 20, 10).ToList(); // assertions // proper quantities // should always be the same number of results as there is quotes Assert.AreEqual(502, results.Count); Assert.AreEqual(448, results.Where(x => x.Pmo != null).Count()); Assert.AreEqual(439, results.Where(x => x.Signal != null).Count()); // sample values PmoResult r1 = results[92]; Assert.AreEqual(0.6159, Math.Round((double)r1.Pmo, 4)); Assert.AreEqual(0.5582, Math.Round((double)r1.Signal, 4)); PmoResult r2 = results[501]; Assert.AreEqual(-2.7016, Math.Round((double)r2.Pmo, 4)); Assert.AreEqual(-2.3117, Math.Round((double)r2.Signal, 4)); }
public void GetPmoTest() { IEnumerable <PmoResult> results = Indicator.GetPmo(history, 35, 20, 10); // assertions // proper quantities // should always be the same number of results as there is history Assert.AreEqual(502, results.Count()); Assert.AreEqual(448, results.Where(x => x.Pmo != null).Count()); Assert.AreEqual(439, results.Where(x => x.Signal != null).Count()); // sample values PmoResult r1 = results.Where(x => x.Index == 93).FirstOrDefault(); Assert.AreEqual(0.6159m, Math.Round((decimal)r1.Pmo, 4)); Assert.AreEqual(0.5582m, Math.Round((decimal)r1.Signal, 4)); PmoResult r2 = results.Where(x => x.Index == 502).FirstOrDefault(); Assert.AreEqual(-2.7016m, Math.Round((decimal)r2.Pmo, 4)); Assert.AreEqual(-2.3117m, Math.Round((decimal)r2.Signal, 4)); }