// ULCER INDEX (UI) public static IEnumerable <UlcerIndexResult> GetUlcerIndex <TQuote>( IEnumerable <TQuote> history, int lookbackPeriod = 14) where TQuote : IQuote { // sort history List <TQuote> historyList = history.Sort(); // check parameter arguments ValidateUlcer(history, lookbackPeriod); // initialize List <UlcerIndexResult> results = new List <UlcerIndexResult>(historyList.Count); // roll through history for (int i = 0; i < historyList.Count; i++) { TQuote h = historyList[i]; int index = i + 1; UlcerIndexResult result = new UlcerIndexResult { Date = h.Date }; if (index >= lookbackPeriod) { double?sumSquared = 0; for (int p = index - lookbackPeriod; p < index; p++) { TQuote d = historyList[p]; int dIndex = p + 1; decimal maxClose = 0; for (int q = index - lookbackPeriod; q < dIndex; q++) { TQuote dd = historyList[q]; if (dd.Close > maxClose) { maxClose = dd.Close; } } decimal?percentDrawdown = (maxClose == 0) ? null : 100 * (d.Close - maxClose) / maxClose; sumSquared += (double?)(percentDrawdown * percentDrawdown); } result.UI = (sumSquared == null) ? null : (decimal)Math.Sqrt((double)sumSquared / lookbackPeriod); } results.Add(result); } return(results); }
// ULCER INDEX (UI) public static IEnumerable <UlcerIndexResult> GetUlcerIndex(IEnumerable <Quote> history, int lookbackPeriod = 14) { // clean quotes history = Cleaners.PrepareHistory(history); // exceptions int qtyHistory = history.Count(); int minHistory = lookbackPeriod; if (qtyHistory < minHistory) { throw new BadHistoryException("Insufficient history provided for Ulcer Index. " + string.Format("You provided {0} periods of history when {1} is required.", qtyHistory, minHistory)); } // initialize List <UlcerIndexResult> results = new List <UlcerIndexResult>(); // preliminary data foreach (Quote h in history) { UlcerIndexResult result = new UlcerIndexResult { Index = (int)h.Index, Date = h.Date }; if (h.Index >= lookbackPeriod) { IEnumerable <Quote> period = history .Where(x => x.Index > (h.Index - lookbackPeriod) && x.Index <= h.Index); double sumSquared = 0; foreach (Quote p in period) { decimal maxClose = period .Where(x => x.Index <= p.Index) .Select(x => x.Close) .Max(); decimal percentDrawdown = 100 * (p.Close - maxClose) / maxClose; sumSquared += (double)(percentDrawdown * percentDrawdown); } result.UI = (decimal)Math.Sqrt(sumSquared / lookbackPeriod); } results.Add(result); } return(results); }
// ULCER INDEX (UI) public static IEnumerable <UlcerIndexResult> GetUlcerIndex(IEnumerable <Quote> history, int lookbackPeriod = 14) { // clean quotes Cleaners.PrepareHistory(history); // validate parameters ValidateUlcer(history, lookbackPeriod); // initialize List <Quote> historyList = history.ToList(); List <UlcerIndexResult> results = new List <UlcerIndexResult>(); // roll through history for (int i = 0; i < historyList.Count; i++) { Quote h = historyList[i]; UlcerIndexResult result = new UlcerIndexResult { 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(); double sumSquared = 0; foreach (Quote p in period) { decimal maxClose = period .Where(x => x.Index <= p.Index) .Select(x => x.Close) .Max(); decimal percentDrawdown = 100 * (p.Close - maxClose) / maxClose; sumSquared += (double)(percentDrawdown * percentDrawdown); } result.UI = (decimal)Math.Sqrt(sumSquared / lookbackPeriod); } results.Add(result); } return(results); }
// ULCER INDEX (UI) public static IEnumerable <UlcerIndexResult> GetUlcerIndex(IEnumerable <Quote> history, int lookbackPeriod = 14) { // clean quotes List <Quote> historyList = Cleaners.PrepareHistory(history).ToList(); // validate parameters ValidateUlcer(history, lookbackPeriod); // initialize List <UlcerIndexResult> results = new List <UlcerIndexResult>(); // roll through history for (int i = 0; i < historyList.Count; i++) { Quote h = historyList[i]; UlcerIndexResult result = new UlcerIndexResult { Index = (int)h.Index, Date = h.Date }; if (h.Index >= lookbackPeriod) { double sumSquared = 0; for (int p = (int)h.Index - lookbackPeriod; p < h.Index; p++) { Quote d = historyList[p]; decimal maxClose = 0; for (int q = (int)h.Index - lookbackPeriod; q < d.Index; q++) { Quote dd = historyList[q]; if (dd.Close > maxClose) { maxClose = dd.Close; } } decimal percentDrawdown = 100 * (d.Close - maxClose) / maxClose; sumSquared += (double)(percentDrawdown * percentDrawdown); } result.UI = (decimal)Math.Sqrt(sumSquared / lookbackPeriod); } results.Add(result); } return(results); }
// ULCER INDEX (UI) public static IEnumerable <UlcerIndexResult> GetUlcerIndex(IEnumerable <Quote> history, int lookbackPeriod = 14) { // clean quotes history = Cleaners.PrepareHistory(history); // initialize List <UlcerIndexResult> results = new List <UlcerIndexResult>(); // preliminary data foreach (Quote h in history) { UlcerIndexResult result = new UlcerIndexResult { Index = (int)h.Index, Date = h.Date }; if (h.Index >= lookbackPeriod) { IEnumerable <Quote> period = history .Where(x => x.Index > (h.Index - lookbackPeriod) && x.Index <= h.Index); double sumSquared = 0; foreach (Quote p in period) { decimal maxClose = period .Where(x => x.Index <= p.Index) .Select(x => x.Close) .Max(); decimal percentDrawdown = 100 * (p.Close - maxClose) / maxClose; sumSquared += (double)(percentDrawdown * percentDrawdown); } result.UI = (decimal)Math.Sqrt(sumSquared / lookbackPeriod); } results.Add(result); } return(results); }