// CHANDELIER EXIT public static IEnumerable <ChandelierResult> GetChandelier( IEnumerable <Quote> history, int lookbackPeriod = 22, decimal multiplier = 3.0m, ChandelierType type = ChandelierType.Long) { // clean quotes Cleaners.PrepareHistory(history); // validate inputs ValidateChandelier(history, lookbackPeriod, multiplier); // initialize List <Quote> historyList = history.ToList(); List <ChandelierResult> results = new List <ChandelierResult>(); List <AtrResult> atrResult = GetAtr(history, lookbackPeriod).ToList(); // uses ATR // roll through history for (int i = 0; i < historyList.Count; i++) { Quote h = historyList[i]; ChandelierResult result = new ChandelierResult { Index = (int)h.Index, Date = h.Date }; // add exit values if (h.Index >= lookbackPeriod) { List <Quote> period = historyList .Where(x => x.Index > (h.Index - lookbackPeriod) && x.Index <= h.Index) .ToList(); decimal atr = (decimal)atrResult[i].Atr; switch (type) { case ChandelierType.Long: decimal maxHigh = period.Select(x => x.High).Max(); result.ChandelierExit = maxHigh - atr * multiplier; break; case ChandelierType.Short: decimal minLow = period.Select(x => x.Low).Min(); result.ChandelierExit = minLow + atr * multiplier; break; default: break; } } results.Add(result); } return(results); }
// CHANDELIER EXIT public static IEnumerable <ChandelierResult> GetChandelier <TQuote>( IEnumerable <TQuote> history, int lookbackPeriod = 22, decimal multiplier = 3.0m, ChandelierType type = ChandelierType.Long) where TQuote : IQuote { // sort history List <TQuote> historyList = history.Sort(); // check parameter arguments ValidateChandelier(history, lookbackPeriod, multiplier); // initialize List <ChandelierResult> results = new List <ChandelierResult>(historyList.Count); List <AtrResult> atrResult = GetAtr(history, lookbackPeriod).ToList(); // uses ATR // roll through history for (int i = 0; i < historyList.Count; i++) { TQuote h = historyList[i]; int index = i + 1; ChandelierResult result = new ChandelierResult { Date = h.Date }; // add exit values if (index >= lookbackPeriod) { decimal atr = (decimal)atrResult[i].Atr; switch (type) { case ChandelierType.Long: decimal maxHigh = 0; for (int p = index - lookbackPeriod; p < index; p++) { TQuote d = historyList[p]; if (d.High > maxHigh) { maxHigh = d.High; } } result.ChandelierExit = maxHigh - atr * multiplier; break; case ChandelierType.Short: decimal minLow = decimal.MaxValue; for (int p = index - lookbackPeriod; p < index; p++) { TQuote d = historyList[p]; if (d.Low < minLow) { minLow = d.Low; } } result.ChandelierExit = minLow + atr * multiplier; break; default: break; } } results.Add(result); } return(results); }
// CHANDELIER EXIT public static IEnumerable <ChandelierResult> GetChandelier( IEnumerable <Quote> history, int lookbackPeriod = 22, decimal multiplier = 3.0m, string variant = "long") { // clean quotes history = Cleaners.PrepareHistory(history); // validate inputs ValidateChandelier(history, lookbackPeriod, multiplier, variant); // initialize List <ChandelierResult> results = new List <ChandelierResult>(); IEnumerable <AtrResult> atrResult = GetAtr(history, lookbackPeriod); // uses ATR decimal prevClose = 0; // roll through history foreach (Quote h in history) { ChandelierResult result = new ChandelierResult { Index = (int)h.Index, Date = h.Date }; // add exit values if (h.Index >= lookbackPeriod) { IEnumerable <Quote> period = history .Where(x => x.Index <= h.Index && x.Index > (h.Index - lookbackPeriod)); decimal atr = (decimal)atrResult .Where(x => x.Index == h.Index).FirstOrDefault().Atr; switch (variant) { case "long": decimal maxHigh = period.Select(x => x.High).Max(); result.ChandelierExit = maxHigh - atr * multiplier; result.IsExitCross = (prevClose >= result.ChandelierExit && h.Close < result.ChandelierExit); result.IsCrossed = (h.Close < result.ChandelierExit); break; case "short": decimal minLow = period.Select(x => x.Low).Min(); result.ChandelierExit = minLow + atr * multiplier; result.IsExitCross = (prevClose <= result.ChandelierExit && h.Close > result.ChandelierExit); result.IsCrossed = (h.Close > result.ChandelierExit); break; default: break; } } prevClose = h.Close; results.Add(result); } return(results); }
// CHANDELIER EXIT public static IEnumerable <ChandelierResult> GetChandelier( IEnumerable <Quote> history, int lookbackPeriod = 22, decimal multiplier = 3.0m, ChandelierType type = ChandelierType.Long) { // clean quotes List <Quote> historyList = Cleaners.PrepareHistory(history).ToList(); // validate inputs ValidateChandelier(history, lookbackPeriod, multiplier); // initialize List <ChandelierResult> results = new List <ChandelierResult>(); List <AtrResult> atrResult = GetAtr(history, lookbackPeriod).ToList(); // uses ATR // roll through history for (int i = 0; i < historyList.Count; i++) { Quote h = historyList[i]; ChandelierResult result = new ChandelierResult { Index = (int)h.Index, Date = h.Date }; // add exit values if (h.Index >= lookbackPeriod) { decimal atr = (decimal)atrResult[i].Atr; switch (type) { case ChandelierType.Long: decimal maxHigh = 0; for (int p = (int)h.Index - lookbackPeriod; p < h.Index; p++) { Quote d = historyList[p]; if (d.High > maxHigh) { maxHigh = d.High; } } result.ChandelierExit = maxHigh - atr * multiplier; break; case ChandelierType.Short: decimal minLow = decimal.MaxValue; for (int p = (int)h.Index - lookbackPeriod; p < h.Index; p++) { Quote d = historyList[p]; if (d.Low < minLow) { minLow = d.Low; } } result.ChandelierExit = minLow + atr * multiplier; break; default: break; } } results.Add(result); } return(results); }