From 870ee07b32aeae2b88991decddb5779dcffe0be0 Mon Sep 17 00:00:00 2001 From: Dave Skender <8432125+DaveSkender@users.noreply.github.com> Date: Sun, 5 Sep 2021 23:33:34 -0400 Subject: [PATCH] add Detrended Price Oscillator (#552) +semver: minor --- docs/_indicators/Dpo.md | 67 +++ docs/assets/charts/Dpo.png | Bin 0 -> 44724 bytes docs/indicators.md | 1 + src/A-D/Dpo/Dpo.Models.cs | 11 + src/A-D/Dpo/Dpo.cs | 102 +++++ src/A-D/Dpo/info.xml | 16 + tests/indicators/A-D/Dpo/Dpo.Calc.xlsx | Bin 0 -> 50347 bytes tests/indicators/A-D/Dpo/Test.Dpo.cs | 87 ++++ tests/indicators/A-D/Dpo/data.csv | 503 +++++++++++++++++++++++ tests/indicators/Tests.Indicators.csproj | 3 + tests/performance/Perf.Indicators.cs | 8 +- 11 files changed, 797 insertions(+), 1 deletion(-) create mode 100644 docs/_indicators/Dpo.md create mode 100644 docs/assets/charts/Dpo.png create mode 100644 src/A-D/Dpo/Dpo.Models.cs create mode 100644 src/A-D/Dpo/Dpo.cs create mode 100644 src/A-D/Dpo/info.xml create mode 100644 tests/indicators/A-D/Dpo/Dpo.Calc.xlsx create mode 100644 tests/indicators/A-D/Dpo/Test.Dpo.cs create mode 100644 tests/indicators/A-D/Dpo/data.csv diff --git a/docs/_indicators/Dpo.md b/docs/_indicators/Dpo.md new file mode 100644 index 000000000..bc3e18551 --- /dev/null +++ b/docs/_indicators/Dpo.md @@ -0,0 +1,67 @@ +--- +title: Detrended Price Oscillator (DPO) +permalink: /indicators/Dpo/ +layout: default +--- + +# {{ page.title }} + +[Detrended Price Oscillator](https://en.wikipedia.org/wiki/Detrended_price_oscillator) depicts the difference between price and an offset simple moving average. It is used to identify trend cycles and duration. +[[Discuss] :speech_balloon:]({{site.github.repository_url}}/discussions/551 "Community discussion about this indicator") + +![image]({{site.baseurl}}/assets/charts/Dpo.png) + +```csharp +// usage +IEnumerable results = + quotes.GetDpo(lookbackPeriods); +``` + +## Parameters + +| name | type | notes +| -- |-- |-- +| `lookbackPeriods` | int | Number of periods (`N`) in the moving average. Must be greater than 0. + +### Historical quotes requirements + +You must have at least `N` historical quotes. + +`quotes` is an `IEnumerable` collection of historical price quotes. It should have a consistent frequency (day, hour, minute, etc). See [the Guide]({{site.baseurl}}/guide#historical-quotes) for more information. + +## Response + +```csharp +IEnumerable +``` + +- This method returns a time series of all available indicator values for the `quotes` provided. +- It always returns the same number of elements as there are in the historical quotes. +- It does not return a single incremental indicator value. +- The first `N/2-2` and last `N/2+1` periods will be `null` since they cannot be calculated. + +### DpoResult + +| name | type | notes +| -- |-- |-- +| `Date` | DateTime | Date +| `Sma` | decimal | Simple moving average offset by `N/2+1` periods +| `Dpo` | decimal | Detrended Price Oscillator (DPO) + +### Utilities + +- [.ConvertToQuotes()]({{site.baseurl}}/utilities#convert-to-quotes) +- [.Find(lookupDate)]({{site.baseurl}}/utilities#find-indicator-result-by-date) +- [.RemoveWarmupPeriods(qty)]({{site.baseurl}}/utilities#remove-warmup-periods) + +See [Utilities and Helpers]({{site.baseurl}}/utilities#utilities-for-indicator-results) for more information. + +## Example + +```csharp +// fetch historical quotes from your feed (your method) +IEnumerable quotes = GetHistoryFromFeed("SPY"); + +// calculate +IEnumerable results = quotes.GetDpo(14); +``` diff --git a/docs/assets/charts/Dpo.png b/docs/assets/charts/Dpo.png new file mode 100644 index 0000000000000000000000000000000000000000..3371d6879789d33a7538e8672638e3add16e859e GIT binary patch literal 44724 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

J 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 G5&sYS|F+)% literal 0 HcmV?d00001 diff --git a/docs/indicators.md b/docs/indicators.md index 1c4af8d48..0d528f1c8 100644 --- a/docs/indicators.md +++ b/docs/indicators.md @@ -46,6 +46,7 @@ redirect_from: - [ConnorsRSI](../indicators/ConnorsRsi/#content) - [Commodity Channel Index](../indicators/Cci/#content) +- [Detrended Price Oscillator (DPO)](../indicators/Dpo/#content) - [Relative Strength Index (RSI)](../indicators/Rsi/#content) - [ROC with Bands](../indicators/Roc/#roc-with-bands) - [Stochastic Oscillator](../indicators/Stoch/#content) and [KDJ Index](../indicators/Stoch/#content) diff --git a/src/A-D/Dpo/Dpo.Models.cs b/src/A-D/Dpo/Dpo.Models.cs new file mode 100644 index 000000000..a1634d680 --- /dev/null +++ b/src/A-D/Dpo/Dpo.Models.cs @@ -0,0 +1,11 @@ +using System; + +namespace Skender.Stock.Indicators +{ + [Serializable] + public class DpoResult : ResultBase + { + public decimal? Sma { get; set; } + public decimal? Dpo { get; set; } + } +} diff --git a/src/A-D/Dpo/Dpo.cs b/src/A-D/Dpo/Dpo.cs new file mode 100644 index 000000000..fea9ca5e1 --- /dev/null +++ b/src/A-D/Dpo/Dpo.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Skender.Stock.Indicators +{ + public static partial class Indicator + { + // DETRENDED PRICE OSCILLATOR (DPO) + /// + /// + public static IEnumerable GetDpo( + this IEnumerable quotes, + int lookbackPeriods) + where TQuote : IQuote + { + + // sort quotes + List quotesList = quotes.Sort(); + + // check parameter arguments + ValidateDpo(quotes, lookbackPeriods); + + // initialize + int size = quotesList.Count; + int offset = lookbackPeriods / 2 + 1; + List sma = quotes.GetSma(lookbackPeriods).ToList(); + List results = new(size); + + // roll through quotes + for (int i = 0; i < size; i++) + { + TQuote q = quotesList[i]; + + DpoResult r = new() + { + Date = q.Date + }; + results.Add(r); + + if (i >= lookbackPeriods - offset - 1 && i < size - offset) + { + SmaResult s = sma[i + offset]; + r.Sma = s.Sma; + r.Dpo = q.Close - s.Sma; + } + } + + return results; + } + + + // convert to quotes + /// + /// + public static IEnumerable ConvertToQuotes( + this IEnumerable results) + { + return results + .Where(x => x.Dpo != null) + .Select(x => new Quote + { + Date = x.Date, + Open = (decimal)x.Dpo, + High = (decimal)x.Dpo, + Low = (decimal)x.Dpo, + Close = (decimal)x.Dpo, + Volume = (decimal)x.Dpo + }) + .ToList(); + } + + + // parameter validation + private static void ValidateDpo( + IEnumerable quotes, + int lookbackPeriods) + where TQuote : IQuote + { + + // check parameter arguments + if (lookbackPeriods <= 0) + { + throw new ArgumentOutOfRangeException(nameof(lookbackPeriods), lookbackPeriods, + "Lookback periods must be greater than 0 for DPO."); + } + + // check quotes + int qtyHistory = quotes.Count(); + int minHistory = lookbackPeriods; + if (qtyHistory < minHistory) + { + string message = string.Format(EnglishCulture, + "Insufficient quotes provided for Detrended Price Oscillator. " + + "You provided {0} periods of quotes when at least {1} are required.", + qtyHistory, minHistory); + + throw new BadQuotesException(nameof(quotes), message); + } + } + } +} diff --git a/src/A-D/Dpo/info.xml b/src/A-D/Dpo/info.xml new file mode 100644 index 000000000..ab23025d7 --- /dev/null +++ b/src/A-D/Dpo/info.xml @@ -0,0 +1,16 @@ + + + +

+ Detrended Price Oscillator (DPO) depicts the difference between price and an offset simple moving average. + See + documentation + for more information. + + Configurable Quote type. See Guide for more information. + Historical price quotes. + Number of periods in the lookback window. + Time series of DPO values. + Invalid parameter value provided. + Insufficient quotes provided. + diff --git a/tests/indicators/A-D/Dpo/Dpo.Calc.xlsx b/tests/indicators/A-D/Dpo/Dpo.Calc.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..b107a40b21fff904c1cad3c8372f4025c02f0052 GIT binary patch literal 50347 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 act = quotes.GetDpo(14) + .ToList(); + + // get test data + List exp = File.ReadAllLines("A-D/Dpo/data.csv") + .Skip(1) + .Select(t => + { + string[] csv = t.Split(","); + return new DpoResult + { + Date = Convert.ToDateTime(csv[1], englishCulture), + Sma = decimal.TryParse(csv[6], out decimal sma) ? sma : null, + Dpo = decimal.TryParse(csv[7], out decimal dpo) ? dpo : null + }; + }) + .ToList(); + + // assertions + Assert.AreEqual(exp.Count, act.Count); + + // compare all values + for (int i = 0; i < exp.Count; i++) + { + DpoResult e = exp[i]; + DpoResult a = act[i]; + + Assert.AreEqual(e.Date, a.Date); + Assert.AreEqual(e.Sma, a.Sma == null + ? a.Sma + : Math.Round((decimal)a.Sma, 5), + $"at index {i}"); + Assert.AreEqual(e.Dpo, a.Dpo == null + ? a.Dpo + : Math.Round((decimal)a.Dpo, 5), + $"at index {i}"); + } + } + + [TestMethod] + public void ConvertToQuotes() + { + List newQuotes = quotes.GetDpo(14) + .ConvertToQuotes() + .ToList(); + + Assert.AreEqual(489, newQuotes.Count); + + Quote q = newQuotes.LastOrDefault(); + Assert.AreEqual(2.18214m, Math.Round(q.Close, 5)); + } + + [TestMethod] + public void BadData() + { + IEnumerable r = badQuotes.GetDpo(5); + Assert.AreEqual(502, r.Count()); + } + + [TestMethod] + public void Exceptions() + { + // bad SMA period + Assert.ThrowsException(() => + quotes.GetDpo(0)); + + // insufficient quotes + Assert.ThrowsException(() => + Indicator.GetDpo(TestData.GetDefault(10), 11)); + } + } +} diff --git a/tests/indicators/A-D/Dpo/data.csv b/tests/indicators/A-D/Dpo/data.csv new file mode 100644 index 000000000..01b678c6b --- /dev/null +++ b/tests/indicators/A-D/Dpo/data.csv @@ -0,0 +1,503 @@ +i,date,open,high,low,close,sma,dpo +0,2017-01-03,212.61,213.35,211.52,212.8,, +1,2017-01-04,213.16,214.22,213.15,214.06,, +2,2017-01-05,213.77,214.06,213.02,213.89,, +3,2017-01-06,214.02,215.17,213.42,214.66,, +4,2017-01-09,214.38,214.53,213.91,213.95,, +5,2017-01-10,213.97,214.89,213.52,213.95,213.97571,-0.02571 +6,2017-01-11,213.86,214.55,213.13,214.55,214.13500,0.41500 +7,2017-01-12,213.99,214.22,212.53,214.02,214.33714,-0.31714 +8,2017-01-13,214.21,214.84,214.17,214.51,214.53500,-0.02500 +9,2017-01-17,213.81,214.25,213.33,213.75,214.65357,-0.90357 +10,2017-01-18,214.02,214.27,213.42,214.22,214.72714,-0.50714 +11,2017-01-19,214.31,214.46,212.96,213.43,214.79929,-1.36929 +12,2017-01-20,214.18,214.75,213.49,214.21,214.83500,-0.62500 +13,2017-01-23,213.85,214.28,212.83,213.66,214.91857,-1.25857 +14,2017-01-24,213.89,215.48,213.77,215.03,215.07286,-0.04286 +15,2017-01-25,216.07,216.89,215.89,216.89,215.25357,1.63643 +16,2017-01-26,216.73,217.02,216.36,216.66,215.40143,1.25857 +17,2017-01-27,216.75,216.91,216.12,216.32,215.62643,0.69357 +18,2017-01-30,215.57,215.59,213.9,214.98,215.88714,-0.90714 +19,2017-01-31,214.44,215.03,213.82,214.96,216.24857,-1.28857 +20,2017-02-01,215.65,215.96,214.4,215.05,216.59714,-1.54714 +21,2017-02-02,214.65,215.5,214.29,215.19,216.87571,-1.68571 +22,2017-02-03,216.18,216.87,215.84,216.67,217.25286,-0.58286 +23,2017-02-06,216.23,216.66,215.92,216.28,217.64071,-1.36071 +24,2017-02-07,216.71,216.97,216.09,216.29,218.14929,-1.85929 +25,2017-02-08,215.98,216.72,215.7,216.58,218.75429,-2.17429 +26,2017-02-09,216.88,218.19,216.84,217.86,219.33857,-1.47857 +27,2017-02-10,218.24,218.97,217.88,218.72,219.92357,-1.20357 +28,2017-02-13,219.26,220.19,219.23,219.91,220.42286,-0.51286 +29,2017-02-14,219.71,220.8,219.33,220.79,220.97500,-0.18500 +30,2017-02-15,220.55,222.15,220.5,221.94,221.48357,0.45643 +31,2017-02-16,221.98,222.16,220.93,221.75,222.19429,-0.44429 +32,2017-02-17,221.03,222.1,221.01,222.1,222.71214,-0.61214 +33,2017-02-21,222.51,223.62,222.5,223.43,223.17857,0.25143 +34,2017-02-22,222.98,223.47,222.8,223.23,223.51214,-0.28214 +35,2017-02-23,223.79,223.81,222.55,223.38,223.73500,-0.35500 +36,2017-02-24,222.45,223.71,222.41,223.66,223.84571,-0.18571 +37,2017-02-27,223.57,224.2,223.29,224.01,223.99071,0.01929 +38,2017-02-28,223.6,223.86,222.98,223.41,224.16643,-0.75643 +39,2017-03-01,225.22,227.04,225.2,226.53,224.25500,2.27500 +40,2017-03-02,226.33,226.34,225.05,225.11,224.29643,0.81357 +41,2017-03-03,225.01,225.43,224.6,225.25,224.46571,0.78429 +42,2017-03-06,224.38,224.97,223.92,224.58,224.58357,-0.00357 +43,2017-03-07,224.25,224.64,223.68,223.91,224.64786,-0.73786 +44,2017-03-08,224.23,224.51,223.34,223.49,224.73714,-1.24714 +45,2017-03-09,223.62,224.13,222.72,223.78,224.39786,-0.61786 +46,2017-03-10,224.82,224.87,223.52,224.56,224.19714,0.36286 +47,2017-03-13,224.49,224.72,224.13,224.67,223.96929,0.70071 +48,2017-03-14,224.08,224.13,223.14,223.81,223.77786,0.03214 +49,2017-03-15,224.44,226.21,224.18,225.75,223.61786,2.13214 +50,2017-03-16,225.9,225.99,224.95,225.31,223.60357,1.70643 +51,2017-03-17,225.59,225.8,224.91,224.91,223.58357,1.32643 +52,2017-03-20,224.91,225.22,224.24,224.66,223.55857,1.10143 +53,2017-03-21,225.33,225.46,221.64,221.78,223.48857,-1.70857 +54,2017-03-22,221.82,222.61,221.13,222.3,223.45214,-1.15214 +55,2017-03-23,222.04,223.31,221.66,222.06,223.28714,-1.22714 +56,2017-03-24,222.4,223.02,221.05,221.9,223.10643,-1.20643 +57,2017-03-27,220.07,221.96,219.77,221.67,222.99857,-1.32857 +58,2017-03-28,221.34,223.75,221.22,223.29,222.89214,0.39786 +59,2017-03-29,222.97,223.75,222.72,223.5,223.00143,0.49857 +60,2017-03-30,223.43,224.43,223.24,224.21,223.05429,1.15571 +61,2017-03-31,223.84,224.42,223.63,223.69,223.05429,0.63571 +62,2017-04-03,223.74,223.96,221.95,223.3,222.96286,0.33714 +63,2017-04-04,222.98,223.53,222.56,223.44,223.02786,0.41214 +64,2017-04-05,224.18,225.25,222.55,222.78,222.92929,-0.14929 +65,2017-04-06,222.93,223.97,222.44,223.4,222.78643,0.61357 +66,2017-04-07,223.13,223.93,222.64,223.17,222.72214,0.44786 +67,2017-04-10,223.33,224.18,222.73,223.31,222.64429,0.66571 +68,2017-04-11,222.89,223.15,221.41,223.04,222.76857,0.27143 +69,2017-04-12,222.74,222.95,221.82,222.06,222.97643,-0.91643 +70,2017-04-13,221.69,222.5,220.62,220.62,223.22143,-2.60143 +71,2017-04-17,221.19,222.58,220.97,222.58,223.43571,-0.85571 +72,2017-04-18,221.77,222.5,221.16,221.91,223.63143,-1.72143 +73,2017-04-19,222.53,222.94,221.26,221.5,223.85786,-2.35786 +74,2017-04-20,222.18,223.79,221.83,223.31,224.10929,-0.79929 +75,2017-04-21,223.22,223.28,222.16,222.6,224.41143,-1.81143 +76,2017-04-24,225.05,225.27,222.57,225.04,224.83500,0.20500 +77,2017-04-25,225.75,226.73,225.65,226.35,225.18214,1.16786 +78,2017-04-26,226.31,227.28,226.16,226.21,225.57500,0.63500 +79,2017-04-27,226.56,226.73,225.81,226.4,225.98214,0.41786 +80,2017-04-28,226.68,226.71,225.76,225.91,226.28929,-0.37929 +81,2017-05-01,226.48,226.94,226.02,226.48,226.61357,-0.13357 +82,2017-05-02,226.63,226.76,226.12,226.56,226.73643,-0.17643 +83,2017-05-03,226.11,226.66,225.55,226.29,226.85500,-0.56500 +84,2017-05-04,226.62,226.71,225.62,226.55,226.96857,-0.41857 +85,2017-05-05,226.96,227.46,226.48,227.44,226.78000,0.66000 +86,2017-05-08,227.49,227.65,226.94,227.41,226.69071,0.71929 +87,2017-05-09,227.69,227.91,226.82,227.2,226.66500,0.53500 +88,2017-05-10,227.15,227.61,226.92,227.61,226.71571,0.89429 +89,2017-05-11,227.11,227.32,225.95,227.14,226.82214,0.31786 +90,2017-05-12,226.87,227.19,226.47,226.76,226.94786,-0.18786 +91,2017-05-15,227.23,228.15,227.21,228.01,227.08786,0.92214 +92,2017-05-16,228.34,228.36,227.38,227.8,227.22643,0.57357 +93,2017-05-17,225.93,226.44,223.7,223.76,227.36571,-3.60571 +94,2017-05-18,223.68,225.59,223.39,224.66,227.47143,-2.81143 +95,2017-05-19,225.2,226.86,225.14,226.12,227.74143,-1.62143 +96,2017-05-22,226.68,227.45,226.61,227.27,228.09357,-0.82357 +97,2017-05-23,227.68,227.96,227.26,227.78,228.34357,-0.56357 +98,2017-05-24,228.03,228.42,227.66,228.31,228.55571,-0.24571 +99,2017-05-25,228.87,229.7,228.64,229.4,229.08714,0.31286 +100,2017-05-26,229.19,229.53,229.1,229.35,229.56286,-0.21286 +101,2017-05-30,229,229.43,228.83,229.15,229.90857,-0.75857 +102,2017-05-31,229.47,229.51,228.34,229.09,230.16929,-1.07929 +103,2017-06-01,229.6,230.94,229.28,230.92,230.47429,0.44571 +104,2017-06-02,230.97,231.86,230.65,231.69,230.72000,0.97000 +105,2017-06-05,231.5,231.81,231.3,231.51,230.85643,0.65357 +106,2017-06-06,230.9,231.51,230.69,230.77,231.00000,-0.23000 +107,2017-06-07,231.14,231.45,230.41,231.2,231.29500,-0.09500 +108,2017-06-08,231.31,231.84,230.74,231.32,231.48214,-0.16214 +109,2017-06-09,231.61,232.48,229.58,230.96,231.53429,-0.57429 +110,2017-06-12,230.7,230.97,229.99,230.92,231.52429,-0.60429 +111,2017-06-13,231.51,232.1,231.13,232.05,231.54643,0.50357 +112,2017-06-14,232.34,232.35,230.85,231.75,231.63286,0.11714 +113,2017-06-15,230.27,231.44,229.97,231.31,231.55500,-0.24500 +114,2017-06-16,231.48,231.54,230.4,231.36,231.61571,-0.25571 +115,2017-06-19,232.26,233.35,232.16,233.28,231.55643,1.72357 +116,2017-06-20,232.89,232.9,231.69,231.71,231.53071,0.17929 +117,2017-06-21,232.1,232.26,231.14,231.65,231.45214,0.19786 +118,2017-06-22,231.66,232.21,231.36,231.55,231.43286,0.11714 +119,2017-06-23,231.61,232.19,231.19,231.82,231.29357,0.52643 +120,2017-06-26,232.56,233.02,231.74,231.98,231.25714,0.72286 +121,2017-06-27,231.74,232.06,230.09,230.11,231.10143,-0.99143 +122,2017-06-28,231.22,232.38,230.97,232.17,231.04571,1.12429 +123,2017-06-29,232.33,232.39,228.8,230.13,231.11786,-0.98786 +124,2017-06-30,231.01,231.42,230.34,230.56,231.22500,-0.66500 +125,2017-07-03,231.59,232.06,230.95,230.95,231.39071,-0.44071 +126,2017-07-05,231.35,231.71,230.46,231.48,231.54286,-0.06286 +127,2017-07-06,230.64,230.77,229.16,229.36,231.83786,-2.47786 +128,2017-07-07,229.99,231.01,229.38,230.85,232.07571,-1.22571 +129,2017-07-10,230.7,231.51,230.52,231.1,232.46714,-1.36714 +130,2017-07-11,230.9,231.27,229.65,230.93,232.81286,-1.88286 +131,2017-07-12,231.99,232.84,231.99,232.66,233.12643,-0.46643 +132,2017-07-13,232.67,233.18,232.42,233.05,233.44286,-0.39286 +133,2017-07-14,233.06,234.53,232.95,234.14,233.91143,0.22857 +134,2017-07-17,234.05,234.47,233.92,234.11,234.25786,-0.14786 +135,2017-07-18,233.66,234.29,233.29,234.24,234.56714,-0.32714 +136,2017-07-19,234.58,235.51,234.57,235.5,234.87857,0.62143 +137,2017-07-20,235.78,235.91,235.01,235.61,235.10429,0.50571 +138,2017-07-21,234.98,235.43,234.73,235.4,235.31000,0.09000 +139,2017-07-24,235.31,235.49,234.83,235.34,235.40571,-0.06571 +140,2017-07-25,236.16,236.28,235.67,235.91,235.53357,0.37643 +141,2017-07-26,236.23,236.27,235.64,235.92,235.68357,0.23643 +142,2017-07-27,236.43,236.47,234.26,235.7,235.70214,-0.00214 +143,2017-07-28,235.18,235.57,234.68,235.43,235.71214,-0.28214 +144,2017-07-31,235.87,235.97,235.07,235.29,235.49929,-0.20929 +145,2017-08-01,235.95,235.99,235.24,235.82,235.31571,0.50429 +146,2017-08-02,235.96,236.09,234.91,235.93,235.25571,0.67429 +147,2017-08-03,235.81,235.84,235.17,235.48,235.19357,0.28643 +148,2017-08-04,236.01,236.27,235.49,235.9,235.17643,0.72357 +149,2017-08-07,235.98,236.34,235.87,236.34,234.91643,1.42357 +150,2017-08-08,236,237.33,235.35,235.76,234.64000,1.12000 +151,2017-08-09,235.01,235.81,234.62,235.75,234.33857,1.41143 +152,2017-08-10,234.84,234.98,232.37,232.42,234.20286,-1.78286 +153,2017-08-11,232.67,233.42,232.41,232.77,234.03929,-1.26929 +154,2017-08-14,234.17,235.31,234.13,235.07,233.80643,1.26357 +155,2017-08-15,235.49,235.51,234.71,235.05,233.58143,1.46857 +156,2017-08-16,235.62,236.06,234.99,235.46,233.39857,2.06143 +157,2017-08-17,234.79,235.13,231.79,231.79,233.23500,-1.44500 +158,2017-08-18,231.6,232.83,230.94,231.42,233.38857,-1.96857 +159,2017-08-21,231.36,231.89,230.58,231.6,233.61786,-2.01786 +160,2017-08-22,232.24,234.2,232.22,234.03,233.70643,0.32357 +161,2017-08-23,232.97,233.65,232.81,233.19,233.67571,-0.48571 +162,2017-08-24,233.61,233.78,232.41,232.64,233.67286,-1.03286 +163,2017-08-25,233.51,234.19,233.02,233.19,233.93000,-0.74000 +164,2017-08-28,233.77,233.8,232.74,233.2,234.19357,-0.99357 +165,2017-08-29,231.76,233.75,231.63,233.46,234.62357,-1.16357 +166,2017-08-30,233.44,234.87,233.24,234.57,234.93714,-0.36714 +167,2017-08-31,235.25,236.25,234.61,235.98,235.31929,0.66071 +168,2017-09-01,236.39,236.78,236.15,236.31,235.73500,0.57500 +169,2017-09-05,235.76,236.01,233.56,234.62,236.13429,-1.51429 +170,2017-09-06,235.36,235.78,234.78,235.42,236.56929,-1.14929 +171,2017-09-07,235.75,235.77,234.94,235.39,237.00286,-1.61286 +172,2017-09-08,235.07,235.62,234.85,235.11,237.36286,-2.25286 +173,2017-09-11,236.51,237.71,236.49,237.62,237.57643,0.04357 +174,2017-09-12,238.02,238.46,237.82,238.42,237.77000,0.65000 +175,2017-09-13,238.11,238.57,237.98,238.54,238.04929,0.49071 +176,2017-09-14,238.18,238.68,237.99,238.46,238.28214,0.17786 +177,2017-09-15,238.3,238.88,238.19,238.78,238.58286,0.19714 +178,2017-09-18,239.18,239.67,238.87,239.29,238.92429,0.36571 +179,2017-09-19,239.56,239.62,239.17,239.53,239.14714,0.38286 +180,2017-09-20,239.62,239.74,238.52,239.61,239.38714,0.22286 +181,2017-09-21,239.44,239.54,238.78,238.97,239.65571,-0.68571 +182,2017-09-22,238.65,239.2,238.62,239.02,239.95000,-0.93000 +183,2017-09-25,238.74,239.13,237.72,238.53,240.32429,-1.79429 +184,2017-09-26,239,239.27,238.41,238.68,240.64214,-1.96214 +185,2017-09-27,239.44,240.03,238.47,239.6,240.91429,-1.31429 +186,2017-09-28,239.3,239.98,239.2,239.89,241.22643,-1.33643 +187,2017-09-29,239.88,240.82,239.68,240.74,241.61214,-0.87214 +188,2017-10-02,240.98,241.78,240.8,241.78,241.96786,-0.18786 +189,2017-10-03,241.91,242.33,241.69,242.3,242.38000,-0.08000 +190,2017-10-04,242.13,242.85,242.01,242.58,242.80500,-0.22500 +191,2017-10-05,242.95,244.04,242.62,244.02,243.17643,0.84357 +192,2017-10-06,243.53,244.06,243.25,243.74,243.54429,0.19571 +193,2017-10-09,243.99,244.06,243.05,243.34,243.85571,-0.51571 +194,2017-10-10,243.96,244.4,243.37,243.98,244.18357,-0.20357 +195,2017-10-11,243.88,244.37,243.7,244.37,244.40571,-0.03571 +196,2017-10-12,244.02,244.41,243.74,244,244.63857,-0.63857 +197,2017-10-13,244.48,244.61,244,244.3,244.68214,-0.38214 +198,2017-10-16,244.55,244.84,244.18,244.63,244.76786,-0.13786 +199,2017-10-17,244.57,244.85,244.33,244.8,245.02500,-0.22500 +200,2017-10-18,245.21,245.26,244.83,245.04,245.17071,-0.13071 +201,2017-10-19,244.18,245.14,243.72,245.1,245.31643,-0.21643 +202,2017-10-20,245.98,246.4,245.09,246.37,245.51143,0.85857 +203,2017-10-23,246.72,246.75,245.33,245.41,245.69214,-0.28214 +204,2017-10-24,245.88,246.1,245.45,245.84,245.90786,-0.06786 +205,2017-10-25,245.48,245.6,243.39,244.63,246.13929,-1.50929 +206,2017-10-26,245.3,245.59,244.81,244.94,246.34071,-1.40071 +207,2017-10-27,245.76,247.12,244.95,246.94,246.56857,0.37143 +208,2017-10-30,246.33,246.84,245.7,246.02,246.64143,-0.62143 +209,2017-10-31,246.44,246.69,246.08,246.41,246.77714,-0.36714 +210,2017-11-01,247.26,247.63,246.33,246.73,246.89857,-0.16857 +211,2017-11-02,246.66,246.98,245.49,246.83,247.06500,-0.23500 +212,2017-11-03,247,247.7,246.55,247.65,247.12143,0.52857 +213,2017-11-06,247.51,248.18,247.43,248.04,247.18429,0.85571 +214,2017-11-07,248.15,248.52,247.31,247.86,247.26071,0.59929 +215,2017-11-08,247.67,248.39,247.37,248.29,247.33929,0.95071 +216,2017-11-09,246.96,247.6,245.65,247.39,247.51071,-0.12071 +217,2017-11-10,246.96,247.5,246.62,247.31,247.65929,-0.34929 +218,2017-11-13,246.56,247.79,246.52,247.54,247.79000,-0.25000 +219,2017-11-14,246.66,247.08,245.8,246.96,247.88429,-0.92429 +220,2017-11-15,245.9,246.48,244.95,245.73,248.17214,-2.44214 +221,2017-11-16,246.76,248.22,246.72,247.82,248.41857,-0.59857 +222,2017-11-17,247.43,247.79,247,247.09,248.88643,-1.79643 +223,2017-11-20,247.36,247.73,247.09,247.51,249.32214,-1.81214 +224,2017-11-21,248.35,249.33,247.47,249.13,249.72000,-0.59000 +225,2017-11-22,249.14,249.28,248.73,248.91,250.09429,-1.18429 +226,2017-11-24,249.45,249.6,249.29,249.48,250.55929,-1.07929 +227,2017-11-27,249.53,249.86,249.14,249.36,250.93214,-1.57214 +228,2017-11-28,249.87,251.92,249.77,251.89,251.45571,0.43429 +229,2017-11-29,252.03,252.62,251.25,251.74,252.00429,-0.26429 +230,2017-11-30,252.74,254.94,252.66,253.94,252.46929,1.47071 +231,2017-12-01,253.7,254.23,249.87,253.41,252.94786,0.46214 +232,2017-12-04,255.19,255.65,253.05,253.11,253.31071,-0.20071 +233,2017-12-05,253.38,254.07,252.05,252.2,253.83357,-1.63357 +234,2017-12-06,251.89,252.71,251.74,252.24,254.29214,-2.05214 +235,2017-12-07,252.1,253.38,251.96,253.04,254.69071,-1.65071 +236,2017-12-08,253.92,254.43,253,254.42,254.92214,-0.50214 +237,2017-12-11,254.49,255.25,254.39,255.19,255.22929,-0.03929 +238,2017-12-12,255.43,256.15,255.22,255.64,255.55357,0.08643 +239,2017-12-13,255.9,256.38,255.51,255.61,255.92071,-0.31071 +240,2017-12-14,255.93,256.06,254.51,254.56,256.29357,-1.73357 +241,2017-12-15,255.66,257.19,255.6,256.68,256.64714,0.03286 +242,2017-12-18,258.21,258.7,258.1,258.31,256.83286,1.47714 +243,2017-12-19,258.58,258.63,257.24,257.32,257.09500,0.22500 +244,2017-12-20,258.38,258.44,256.86,257.18,257.44214,-0.26214 +245,2017-12-21,257.87,258.49,257.44,257.71,257.86929,-0.15929 +246,2017-12-22,257.73,257.77,257.06,257.65,258.49643,-0.84643 +247,2017-12-26,257.2,257.58,257.04,257.34,259.00643,-1.66643 +248,2017-12-27,257.52,257.86,257.16,257.46,259.44286,-1.98286 +249,2017-12-28,258.01,258.04,257.59,257.99,259.92071,-1.93071 +250,2017-12-29,258.63,258.65,256.81,257.02,260.54643,-3.52643 +251,2018-01-02,257.96,258.9,257.54,258.86,261.25786,-2.39786 +252,2018-01-03,259.04,260.66,259.04,260.5,261.90857,-1.40857 +253,2018-01-04,261.2,262.12,260.57,261.59,262.76286,-1.17286 +254,2018-01-05,262.46,263.47,261.92,263.34,263.57643,-0.23643 +255,2018-01-08,263.23,263.99,262.91,263.82,264.43929,-0.61929 +256,2018-01-09,264.28,265.1,263.97,264.42,265.52857,-1.10857 +257,2018-01-10,263.59,264.3,262.86,264.01,266.52714,-2.51714 +258,2018-01-11,264.62,265.94,264.44,265.94,267.40143,-1.46143 +259,2018-01-12,266.23,267.86,265.9,267.67,268.20571,-0.53571 +260,2018-01-16,269.05,269.76,266,266.76,269.11071,-2.35071 +261,2018-01-17,267.78,269.72,266.76,269.3,269.85071,-0.55071 +262,2018-01-18,269.17,269.64,268.31,268.85,270.34714,-1.49714 +263,2018-01-19,269.48,270.07,268.85,270.07,270.88286,-0.81286 +264,2018-01-22,269.84,272.27,269.78,272.27,271.25857,1.01143 +265,2018-01-23,272.31,273.16,271.96,272.84,271.08857,1.75143 +266,2018-01-24,273.55,274.2,271.45,272.74,270.19143,2.54857 +267,2018-01-25,273.68,273.79,271.99,272.85,269.47071,3.37929 +268,2018-01-26,273.77,276.06,273.49,276.01,268.68143,7.32857 +269,2018-01-29,275.39,275.87,274.01,274.18,267.11429,7.06571 +270,2018-01-30,272.18,274.24,270.85,271.37,265.65643,5.71357 +271,2018-01-31,272.3,272.85,270.33,271.51,264.42214,7.08786 +272,2018-02-01,270.71,272.62,270.33,271.2,263.24000,7.96000 +273,2018-02-02,269.75,269.9,265.25,265.29,262.29714,2.99286 +274,2018-02-05,263.37,265.68,253.6,254.2,261.36500,-7.16500 +275,2018-02-06,250.35,259.76,249.16,259.21,260.56929,-1.35929 +276,2018-02-07,258.6,262.32,257.71,257.8,259.85643,-2.05643 +277,2018-02-08,258.13,258.28,248.09,248.13,259.04071,-10.91071 +278,2018-02-09,251.18,253.89,243.59,251.86,258.27143,-6.41143 +279,2018-02-12,254.1,257.16,252.02,255.56,258.22071,-2.66071 +280,2018-02-13,254.24,256.79,253.6,256.19,259.18143,-2.99143 +281,2018-02-14,254.56,260.04,254.55,259.65,259.54571,0.10429 +282,2018-02-15,261.56,262.97,258.86,262.96,259.81929,3.14071 +283,2018-02-16,262.28,265.17,262.23,263.04,260.51214,2.52786 +284,2018-02-20,262,263.58,260.53,261.39,261.03357,0.35643 +285,2018-02-21,261.87,264.59,259.99,260.09,261.50429,-1.41429 +286,2018-02-22,261.1,262.98,259.7,260.43,261.97786,-1.54786 +287,2018-02-23,261.77,264.58,261.25,264.58,262.19714,2.38286 +288,2018-02-26,265.76,267.76,265.11,267.65,262.27071,5.37929 +289,2018-02-27,267.86,268.63,264.24,264.31,262.66714,1.64286 +290,2018-02-28,265.51,266.01,261.29,261.63,263.15714,-1.52714 +291,2018-03-01,261.4,263.1,256.19,257.83,263.61643,-5.78643 +292,2018-03-02,256,259.77,255.05,259.16,263.95357,-4.79357 +293,2018-03-05,257.86,262.83,257.74,262.15,263.97357,-1.82357 +294,2018-03-06,263.22,263.31,261.18,262.82,263.79500,-0.97500 +295,2018-03-07,260.45,263.11,260.24,262.72,263.59857,-0.87857 +296,2018-03-08,263.46,264.13,262.37,263.99,263.62500,0.36500 +297,2018-03-09,265.53,268.59,265.19,268.59,263.88714,4.70286 +298,2018-03-12,268.9,269.59,267.83,268.25,263.58714,4.66286 +299,2018-03-13,269.52,270.07,265.85,266.52,262.68571,3.83429 +300,2018-03-14,267.57,267.77,264.54,265.15,262.22429,2.92571 +301,2018-03-15,265.71,266.41,264.31,264.86,261.45857,3.40143 +302,2018-03-16,265.44,266.3,265.09,265.15,260.54857,4.60143 +303,2018-03-19,264.32,265.34,259.75,261.56,259.53929,2.02071 +304,2018-03-20,261.99,262.7,261.26,262,258.16214,3.83786 +305,2018-03-21,261.96,264.25,261.27,261.5,257.13643,4.36357 +306,2018-03-22,259.06,259.99,254.66,254.96,256.40143,-1.44143 +307,2018-03-23,255.45,256.27,249.32,249.53,255.83071,-6.30071 +308,2018-03-26,253.48,256.67,250.84,256.36,254.83000,1.53000 +309,2018-03-27,257.38,257.96,250.29,252,254.17429,-2.17429 +310,2018-03-28,252.14,253.97,250.04,251.25,253.77429,-2.52429 +311,2018-03-29,252.5,256.5,251.26,254.46,253.31357,1.14643 +312,2018-04-02,253.88,254.44,246.26,248.97,253.47000,-4.50000 +313,2018-04-03,250.32,252.68,248.36,252.16,253.96071,-1.80071 +314,2018-04-04,248.27,255.63,248.13,254.86,254.11357,0.74643 +315,2018-04-05,256.78,257.84,255.59,256.87,254.77571,2.09429 +316,2018-04-06,254.72,256.36,249.48,251.14,255.50500,-4.36500 +317,2018-04-09,252.74,256.1,251.35,252.38,255.90143,-3.52143 +318,2018-04-10,255.54,257.26,254.3,256.4,256.53286,-0.13286 +319,2018-04-11,254.77,256.87,254.69,255.05,256.93357,-1.88357 +320,2018-04-12,256.5,258.18,256.31,257.15,256.89357,0.25643 +321,2018-04-13,258.58,258.71,255.29,256.4,256.75500,-0.35500 +322,2018-04-16,258.18,259.34,257.29,258.5,257.21071,1.28929 +323,2018-04-17,260.44,261.93,259.88,261.27,257.59500,3.67500 +324,2018-04-18,261.75,262.34,260.96,261.46,257.55071,3.90929 +325,2018-04-19,260.75,260.97,258.88,260.01,257.63500,2.37500 +326,2018-04-20,259.93,260.18,256.84,257.81,257.44643,0.36357 +327,2018-04-23,258.44,259.04,256.59,257.77,257.27143,0.49857 +328,2018-04-24,258.89,259.13,252.65,254.3,257.18143,-2.88143 +329,2018-04-25,254.23,255.41,252.24,254.93,256.95571,-2.02571 +330,2018-04-26,256.05,258.42,255.56,257.52,256.71643,0.80357 +331,2018-04-27,258.18,258.51,256.73,257.76,256.75857,1.00143 +332,2018-04-30,258.44,259.04,255.7,255.78,257.13214,-1.35214 +333,2018-05-01,255.16,256.35,253.46,256.23,257.56571,-1.33571 +334,2018-05-02,256.02,256.91,254.08,254.51,258.25643,-3.74643 +335,2018-05-03,253.6,254.66,250.5,253.95,258.77214,-4.82214 +336,2018-05-04,252.89,257.98,252.53,257.24,259.18143,-1.94143 +337,2018-05-07,258.08,259.17,257.32,258.11,259.55786,-1.44786 +338,2018-05-08,257.7,258.5,256.4,258.11,260.02857,-1.91857 +339,2018-05-09,258.84,260.95,258.27,260.6,260.60786,-0.00786 +340,2018-05-10,261.41,263.4,261.3,263.04,261.25786,1.78214 +341,2018-05-11,263.17,264.13,262.61,263.84,261.99929,1.84071 +342,2018-05-14,264.31,265.03,263.37,263.97,262.46714,1.50286 +343,2018-05-15,262.62,262.64,261.11,262.15,262.82786,-0.67786 +344,2018-05-16,262.19,263.75,262.16,263.25,262.97286,0.27714 +345,2018-05-17,262.96,264.21,262.18,263.03,263.18786,-0.15786 +346,2018-05-18,262.65,263.05,261.98,262.37,263.11286,-0.74286 +347,2018-05-21,264,264.93,262.39,264.34,263.16500,1.17500 +348,2018-05-22,264.91,265.2,263.25,263.61,263.29714,0.31286 +349,2018-05-23,262.22,264.36,262.04,264.33,263.57357,0.75643 +350,2018-05-24,263.9,264.2,261.84,263.79,263.93000,-0.14000 +351,2018-05-25,263.16,263.85,262.61,263.16,264.30000,-1.14000 +352,2018-05-29,261.39,262.22,258.92,260.14,264.77357,-4.63357 +353,2018-05-30,261.57,264.09,261.49,263.61,265.13214,-1.52214 +354,2018-05-31,263.16,263.49,261.33,261.99,265.56786,-3.57786 +355,2018-06-01,263.42,264.9,263.34,264.57,265.89071,-1.32071 +356,2018-06-04,265.47,266.1,265.2,265.82,266.30071,-0.48071 +357,2018-06-05,265.97,266.43,265.13,266.02,266.73071,-0.71071 +358,2018-06-06,266.68,268.36,266.01,268.24,267.33714,0.90286 +359,2018-06-07,268.77,269.09,267.22,268.21,267.62214,0.58786 +360,2018-06-08,267.71,269.06,267.53,269,268.05571,0.94429 +361,2018-06-11,269.25,270.15,269.12,269.36,268.18500,1.17500 +362,2018-06-12,269.82,270.11,269,269.71,268.25929,1.45071 +363,2018-06-13,269.97,270.25,268.63,268.85,268.06000,0.79000 +364,2018-06-14,269.8,270.11,268.88,269.53,267.74357,1.78643 +365,2018-06-15,268.67,269.55,267.45,269.18,267.27357,1.90643 +366,2018-06-18,267.59,268.77,267.07,268.63,266.85357,1.77643 +367,2018-06-19,266.14,267.84,265.69,267.6,266.43500,1.16500 +368,2018-06-20,268.35,268.78,267.69,268.06,266.03143,2.02857 +369,2018-06-21,268.05,268.07,265.83,266.38,265.62286,0.75714 +370,2018-06-22,267.76,267.88,266.62,266.86,265.31929,1.54071 +371,2018-06-25,265.6,265.77,261.38,263.23,265.20071,-1.97071 +372,2018-06-26,263.85,264.74,263.02,263.81,265.29357,-1.48357 +373,2018-06-27,264.45,266.01,261.46,261.63,265.52929,-3.89929 +374,2018-06-28,261.57,263.96,260.79,263.12,265.59071,-2.47071 +375,2018-06-29,264.32,265.81,263.37,263.5,265.94643,-2.44643 +376,2018-07-02,261.78,264.24,261.52,264.06,266.28286,-2.22286 +377,2018-07-03,265.05,265.15,262.67,263.13,266.86143,-3.73143 +378,2018-07-05,264.36,265.35,263.19,265.28,267.47714,-2.19714 +379,2018-07-06,265.31,267.93,264.89,267.52,268.28929,-0.76929 +380,2018-07-09,268.62,269.99,268.57,269.93,268.92143,1.00857 +381,2018-07-10,270.43,271.01,270.11,270.9,269.50429,1.39571 +382,2018-07-11,269.2,270.07,268.59,268.92,270.08286,-1.16286 +383,2018-07-12,270.3,271.42,269.64,271.36,270.82571,0.53429 +384,2018-07-13,271.16,271.9,270.67,271.57,271.58214,-0.01214 +385,2018-07-16,271.62,271.78,270.84,271.33,272.13143,-0.80143 +386,2018-07-17,270.48,272.85,270.43,272.43,272.37571,0.05429 +387,2018-07-18,272.51,273.12,272.03,273,272.44857,0.55143 +388,2018-07-19,272.27,272.69,271.45,271.97,272.75857,-0.78857 +389,2018-07-20,271.75,272.44,271.48,271.66,272.86214,-1.20214 +390,2018-07-23,271.44,272.39,271.06,272.16,273.05643,-0.89643 +391,2018-07-24,273.71,274.46,272.58,273.53,273.35214,0.17786 +392,2018-07-25,273.26,276.22,273.21,275.87,273.64143,2.22857 +393,2018-07-26,275.08,275.96,274.97,275.21,273.95500,1.25500 +394,2018-07-27,275.57,275.68,272.34,273.35,274.33357,-0.98357 +395,2018-07-30,273.44,273.61,271.35,271.92,274.70786,-2.78786 +396,2018-07-31,272.76,273.93,272.34,273.26,274.91357,-1.65357 +397,2018-08-01,273.49,274.04,272.1,272.81,274.94786,-2.13786 +398,2018-08-02,271.38,274.48,271.15,274.29,274.94000,-0.65000 +399,2018-08-03,274.43,275.52,274.23,275.47,274.83214,0.63786 +400,2018-08-06,275.51,276.82,275.08,276.48,275.01500,1.46500 +401,2018-08-07,277.21,277.81,277.06,277.39,275.37000,2.02000 +402,2018-08-08,277.21,277.71,276.77,277.27,275.67143,1.59857 +403,2018-08-09,277.34,277.77,276.74,276.9,276.05143,0.84857 +404,2018-08-10,275.32,275.91,274.26,275.04,276.31357,-1.27357 +405,2018-08-13,275.34,276.01,273.69,274.01,276.46500,-2.45500 +406,2018-08-14,274.81,276.02,274.38,275.76,276.66429,-0.90429 +407,2018-08-15,274.28,274.44,272.13,273.7,276.95571,-3.25571 +408,2018-08-16,275.27,276.87,275.23,275.91,277.26571,-1.35571 +409,2018-08-17,275.69,277.37,275.24,276.89,277.71000,-0.82000 +410,2018-08-20,277.38,277.77,276.89,277.48,278.20571,-0.72571 +411,2018-08-21,278.04,279.07,277.52,278.13,278.77500,-0.64500 +412,2018-08-22,277.68,278.54,277.39,277.96,279.18500,-1.22500 +413,2018-08-23,277.77,278.71,277.24,277.59,279.68786,-2.09786 +414,2018-08-24,278.23,279.42,278.17,279.27,279.97286,-0.70286 +415,2018-08-27,280.58,281.59,280.4,281.47,280.14857,1.32143 +416,2018-08-28,281.98,282.09,281.1,281.61,280.31714,1.29286 +417,2018-08-29,281.84,283.37,281.57,283.12,280.50500,2.61500 +418,2018-08-30,282.6,283,281.32,281.98,280.71000,1.27000 +419,2018-08-31,281.53,282.47,280.99,281.98,281.06000,0.92000 +420,2018-09-04,281.53,281.89,280.4,281.5,281.29357,0.20643 +421,2018-09-05,281.11,281.33,279.63,280.74,281.26286,-0.52286 +422,2018-09-06,280.86,281.19,278.77,279.9,281.33143,-1.43143 +423,2018-09-07,278.75,280.42,278.49,279.35,281.31357,-1.96357 +424,2018-09-10,280.46,280.75,279.62,279.84,281.54071,-1.70071 +425,2018-09-11,279.13,281.25,278.75,280.76,281.74929,-0.98929 +426,2018-09-12,280.77,281.49,279.96,280.83,281.92429,-1.09429 +427,2018-09-13,281.99,282.69,281.68,282.49,282.13500,0.35500 +428,2018-09-14,282.71,282.92,281.68,282.54,282.34500,0.19500 +429,2018-09-17,282.48,282.52,280.74,281.04,282.65071,-1.61071 +430,2018-09-18,281.28,283.22,281.25,282.57,282.92357,-0.35357 +431,2018-09-19,282.63,283.33,282.48,282.87,283.20143,-0.33143 +432,2018-09-20,284.25,285.51,282.88,285.16,283.46214,1.69786 +433,2018-09-21,285.97,286.1,284.72,284.9,283.61571,1.28429 +434,2018-09-24,284.27,284.42,283.32,283.95,283.60643,0.34357 +435,2018-09-25,284.45,284.57,283.43,283.69,283.59143,0.09857 +436,2018-09-26,283.85,285.14,282.38,282.84,283.46714,-0.62714 +437,2018-09-27,283.36,284.82,283.06,283.63,283.29214,0.33786 +438,2018-09-28,282.95,284.21,282.91,283.66,282.31929,1.34071 +439,2018-10-01,285.02,285.82,283.91,284.65,280.93786,3.71214 +440,2018-10-02,284.48,285.26,284.07,284.48,279.88786,4.59214 +441,2018-10-03,285.63,286.09,284.25,284.64,278.74857,5.89143 +442,2018-10-04,284.11,284.17,280.68,282.41,278.08786,4.32214 +443,2018-10-05,282.66,283.22,279.27,280.83,277.37429,3.45571 +444,2018-10-08,280.08,281.22,278.57,280.83,276.37643,4.45357 +445,2018-10-09,280.41,281.85,279.81,280.42,275.29714,5.12286 +446,2018-10-10,279.87,279.94,271.13,271.54,274.14357,-2.60357 +447,2018-10-11,270.35,272.13,263.8,265.56,272.88143,-7.32143 +448,2018-10-12,270.05,270.36,265.76,269.25,271.20071,-1.95071 +449,2018-10-15,268.86,270.31,267.64,267.74,269.96429,-2.22429 +450,2018-10-16,269.88,274,269.37,273.59,268.39714,5.19286 +451,2018-10-17,273.63,274.32,270.82,273.64,266.75643,6.88357 +452,2018-10-18,272.62,273.27,268.29,269.69,266.02286,3.66714 +453,2018-10-19,270.4,272.52,268.78,269.54,265.91571,3.62429 +454,2018-10-22,270.27,270.63,267.75,268.33,265.74571,2.58429 +455,2018-10-23,264.37,268.2,262.09,266.97,265.57071,1.39929 +456,2018-10-24,266.69,267.11,258.27,258.88,265.08214,-6.20214 +457,2018-10-25,260.89,265.21,259.77,263.52,264.71071,-1.19071 +458,2018-10-26,259.46,264.42,255.92,258.89,265.03214,-6.14214 +459,2018-10-29,262.27,263.69,253.54,257.45,265.32857,-7.87857 +460,2018-10-30,257.27,261.61,256.73,261.27,265.52071,-4.25071 +461,2018-10-31,264.08,266.6,263.56,264.06,265.44786,-1.38786 +462,2018-11-01,265.01,267.08,263.81,266.87,265.91714,0.95286 +463,2018-11-02,268.08,268.55,263.04,265.29,265.92571,-0.63571 +464,2018-11-05,265.82,267.36,264.76,266.75,266.46143,0.28857 +465,2018-11-06,266.68,268.62,266.62,268.44,267.14929,1.29071 +466,2018-11-07,270.82,274.27,270.35,274.19,267.24214,6.94786 +467,2018-11-08,273.31,274.39,272.44,273.69,266.78857,6.90143 +468,2018-11-09,272.25,272.46,269.47,271.02,266.19643,4.82357 +469,2018-11-12,270.46,270.72,265.39,265.95,265.59429,0.35571 +470,2018-11-13,266.46,268.64,264.66,265.45,265.18357,0.26643 +471,2018-11-14,267.5,267.94,261.93,263.64,264.71500,-1.07500 +472,2018-11-15,262.25,266.9,260.53,266.39,264.26643,2.12357 +473,2018-11-16,265.19,268.08,264.62,267.08,263.81214,3.26786 +474,2018-11-19,266.42,266.74,261.56,262.57,263.66500,-1.09500 +475,2018-11-20,258.92,260.52,256.76,257.71,264.13429,-6.42429 +476,2018-11-21,259.4,260.66,258.58,258.58,264.00857,-5.42857 +477,2018-11-23,256.79,258.39,256.68,256.86,263.98357,-7.12357 +478,2018-11-26,259.33,261.25,258.9,261,263.32500,-2.32500 +479,2018-11-27,259.87,261.88,259.21,261.88,262.65214,-0.77214 +480,2018-11-28,263.05,267.91,261.81,267.91,262.30571,5.60429 +481,2018-11-29,267.06,268.86,265.82,267.33,262.39857,4.93143 +482,2018-11-30,267.16,269.57,266.81,268.96,262.42357,6.53643 +483,2018-12-03,273.47,273.59,270.77,272.52,262.23000,10.29000 +484,2018-12-04,271.61,272.08,263.35,263.69,261.38429,2.30571 +485,2018-12-06,259.46,263.41,256.07,263.29,260.45643,2.83357 +486,2018-12-07,262.92,264.63,256.25,257.17,258.83143,-1.66143 +487,2018-12-10,256.98,258.72,252.34,257.66,256.96286,0.69714 +488,2018-12-11,261.16,261.37,256.11,257.72,254.62500,3.09500 +489,2018-12-12,260.98,262.47,258.93,259.01,251.58714,7.42286 +490,2018-12-13,260.05,260.99,257.71,258.93,250.01000,8.92000 +491,2018-12-14,256.58,257.62,253.54,254.15,248.59357,5.55643 +492,2018-12-17,253.1,254.32,247.37,249.16,247.59214,1.56786 +493,2018-12-18,250.95,251.69,247.13,248.89,246.70786,2.18214 +494,2018-12-19,248.97,253.1,243.3,245.16,, +495,2018-12-20,243.79,245.51,238.71,241.17,, +496,2018-12-21,242.16,245.07,235.52,236.23,, +497,2018-12-24,234.6,236.36,229.92,229.99,, +498,2018-12-26,231.59,241.61,229.42,241.61,, +499,2018-12-27,238.06,243.68,234.52,243.46,, +500,2018-12-28,244.94,246.73,241.87,243.15,, +501,2018-12-31,244.92,245.54,242.87,245.28,, diff --git a/tests/indicators/Tests.Indicators.csproj b/tests/indicators/Tests.Indicators.csproj index f86a00a52..db6cce7ed 100644 --- a/tests/indicators/Tests.Indicators.csproj +++ b/tests/indicators/Tests.Indicators.csproj @@ -31,6 +31,9 @@ + + Always + Always diff --git a/tests/performance/Perf.Indicators.cs b/tests/performance/Perf.Indicators.cs index 452c14a97..8a27854a3 100644 --- a/tests/performance/Perf.Indicators.cs +++ b/tests/performance/Perf.Indicators.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using BenchmarkDotNet.Attributes; using Internal.Tests; using Skender.Stock.Indicators; @@ -153,6 +153,12 @@ public object GetDoubleEma() return h.GetDoubleEma(14); } + [Benchmark] + public object GetDpo() + { + return h.GetDpo(14); + } + [Benchmark] public object GetElderRay() {