public void Standard() { decimal acclerationStep = 0.02m; decimal maxAccelerationFactor = 0.2m; List <ParabolicSarResult> results = Indicator.GetParabolicSar(history, acclerationStep, maxAccelerationFactor) .ToList(); // assertions // proper quantities // should always be the same number of results as there is history Assert.AreEqual(502, results.Count); Assert.AreEqual(488, results.Where(x => x.Sar != null).Count()); // sample values ParabolicSarResult r1 = results[14]; Assert.AreEqual(212.83m, Math.Round((decimal)r1.Sar, 4)); Assert.AreEqual(true, r1.IsReversal); ParabolicSarResult r2 = results[16]; Assert.AreEqual(212.9924m, Math.Round((decimal)r2.Sar, 4)); Assert.AreEqual(false, r2.IsReversal); ParabolicSarResult r3 = results[501]; Assert.AreEqual(229.7662m, Math.Round((decimal)r3.Sar, 4)); Assert.AreEqual(false, r3.IsReversal); }
public void GetParabolicSarTest() { decimal acclerationStep = (decimal)0.02; decimal maxAccelerationFactor = (decimal)0.2; IEnumerable <ParabolicSarResult> results = Indicator.GetParabolicSar(history, acclerationStep, maxAccelerationFactor); // assertions // proper quantities // should always be the same number of results as there is history Assert.AreEqual(502, results.Count()); Assert.AreEqual(488, results.Where(x => x.Sar != null).Count()); // sample values ParabolicSarResult r1 = results.Where(x => x.Index == 15).FirstOrDefault(); Assert.AreEqual(212.83m, Math.Round((decimal)r1.Sar, 4)); Assert.AreEqual(true, r1.IsReversal); ParabolicSarResult r2 = results.Where(x => x.Index == 17).FirstOrDefault(); Assert.AreEqual(212.9924m, Math.Round((decimal)r2.Sar, 4)); Assert.AreEqual(false, r2.IsReversal); ParabolicSarResult r3 = results.Where(x => x.Index == 502).FirstOrDefault(); Assert.AreEqual(229.7662m, Math.Round((decimal)r3.Sar, 4)); Assert.AreEqual(false, r3.IsReversal); }
public void Removed() { decimal acclerationStep = 0.02m; decimal maxAccelerationFactor = 0.2m; List <ParabolicSarResult> results = quotes.GetParabolicSar(acclerationStep, maxAccelerationFactor) .RemoveWarmupPeriods() .ToList(); // assertions Assert.AreEqual(488, results.Count); ParabolicSarResult last = results.LastOrDefault(); Assert.AreEqual(229.7662m, Math.Round((decimal)last.Sar, 4)); Assert.AreEqual(false, last.IsReversal); }
public void Extended() { decimal acclerationStep = 0.02m; decimal maxAccelerationFactor = 0.2m; decimal initialStep = 0.01m; List <ParabolicSarResult> results = quotes.GetParabolicSar( acclerationStep, maxAccelerationFactor, initialStep) .ToList(); // assertions // proper quantities // should always be the same number of results as there is quotes Assert.AreEqual(502, results.Count); Assert.AreEqual(488, results.Where(x => x.Sar != null).Count()); // sample values ParabolicSarResult r14 = results[14]; Assert.AreEqual(212.83m, r14.Sar); Assert.AreEqual(true, r14.IsReversal); ParabolicSarResult r16 = results[16]; Assert.AreEqual(212.9518m, Math.Round((decimal)r16.Sar, 4)); Assert.AreEqual(false, r16.IsReversal); ParabolicSarResult r94 = results[94]; Assert.AreEqual(228.36m, r94.Sar); Assert.AreEqual(false, r94.IsReversal); ParabolicSarResult r486 = results[486]; Assert.AreEqual(273.4148m, r486.Sar); Assert.AreEqual(false, r486.IsReversal); ParabolicSarResult r501 = results[501]; Assert.AreEqual(246.73m, r501.Sar); Assert.AreEqual(false, r501.IsReversal); }
public void GetParabolicSarTest() { decimal acclerationStep = (decimal)0.02; decimal maxAccelerationFactor = (decimal)0.2; IEnumerable <ParabolicSarResult> results = Indicator.GetParabolicSar(history, acclerationStep, maxAccelerationFactor); // assertions // proper quantities // should always be the same number of results as there is history Assert.AreEqual(502, results.Count()); Assert.AreEqual(501, results.Where(x => x.Sar != null).Count()); // sample value ParabolicSarResult result = results.Where(x => x.Date == DateTime.Parse("12/31/2018")).FirstOrDefault(); Assert.AreEqual((decimal)229.7662, Math.Round((decimal)result.Sar, 4)); Assert.AreEqual(true, result.IsRising); Assert.AreEqual(false, result.IsReversal); }
/// <include file='./info.xml' path='indicator/type[@name="Extended"]/*' /> /// public static IEnumerable <ParabolicSarResult> GetParabolicSar <TQuote>( this IEnumerable <TQuote> quotes, decimal accelerationStep, decimal maxAccelerationFactor, decimal initialFactor) where TQuote : IQuote { // sort quotes List <TQuote> quotesList = quotes.SortToList(); // check parameter arguments ValidateParabolicSar( accelerationStep, maxAccelerationFactor, initialFactor); // initialize int length = quotesList.Count; List <ParabolicSarResult> results = new(length); TQuote q0; if (length == 0) { return(results); } else { q0 = quotesList[0]; } decimal accelerationFactor = initialFactor; decimal extremePoint = q0.High; decimal priorSar = q0.Low; bool isRising = true; // initial guess // roll through quotes for (int i = 0; i < length; i++) { TQuote q = quotesList[i]; ParabolicSarResult r = new() { Date = q.Date }; results.Add(r); // skip first one if (i == 0) { continue; } // was rising if (isRising) { decimal sar = priorSar + (accelerationFactor * (extremePoint - priorSar)); // SAR cannot be higher than last two lows if (i >= 2) { decimal minLastTwo = Math.Min( quotesList[i - 1].Low, quotesList[i - 2].Low); sar = Math.Min(sar, minLastTwo); } // turn down if (q.Low < sar) { r.IsReversal = true; r.Sar = extremePoint; isRising = false; accelerationFactor = initialFactor; extremePoint = q.Low; } // continue rising else { r.IsReversal = false; r.Sar = sar; // new high extreme point if (q.High > extremePoint) { extremePoint = q.High; accelerationFactor = Math.Min( accelerationFactor += accelerationStep, maxAccelerationFactor); } } } // was falling else { decimal sar = priorSar - (accelerationFactor * (priorSar - extremePoint)); // SAR cannot be lower than last two highs if (i >= 2) { decimal maxLastTwo = Math.Max( quotesList[i - 1].High, quotesList[i - 2].High); sar = Math.Max(sar, maxLastTwo); } // turn up if (q.High > sar) { r.IsReversal = true; r.Sar = extremePoint; isRising = true; accelerationFactor = initialFactor; extremePoint = q.High; } // continue falling else { r.IsReversal = false; r.Sar = sar; // new low extreme point if (q.Low < extremePoint) { extremePoint = q.Low; accelerationFactor = Math.Min( accelerationFactor += accelerationStep, maxAccelerationFactor); } } } priorSar = (decimal)r.Sar; } // remove first trend to reversal, since it is an invalid guess ParabolicSarResult firstReversal = results .Where(x => x.IsReversal == true) .OrderBy(x => x.Date) .FirstOrDefault(); if (firstReversal != null) { int cutIndex = results.IndexOf(firstReversal); for (int d = 0; d <= cutIndex; d++) { ParabolicSarResult r = results[d]; r.Sar = null; r.IsReversal = null; } } return(results); }