private static IEnumerable <StdDevResult> CalcStdDev( IEnumerable <BasicData> basicData, int lookbackPeriod, int?smaPeriod = null) { // clean data List <BasicData> basicDataList = Cleaners.PrepareBasicData(basicData).ToList(); // validate inputs ValidateStdDev(basicData, lookbackPeriod, smaPeriod); // initialize results List <StdDevResult> results = new List <StdDevResult>(); // roll through history and compute lookback standard deviation foreach (BasicData bd in basicDataList) { StdDevResult result = new StdDevResult { Index = (int)bd.Index, Date = bd.Date, }; if (bd.Index >= lookbackPeriod) { double[] periodValues = new double[lookbackPeriod]; decimal sum = 0m; int n = 0; for (int p = (int)bd.Index - lookbackPeriod; p < bd.Index; p++) { BasicData d = basicDataList[p]; periodValues[n] = (double)d.Value; sum += d.Value; n++; } decimal periodAvg = sum / lookbackPeriod; result.StdDev = (decimal)Functions.StdDev(periodValues); result.ZScore = (bd.Value - periodAvg) / result.StdDev; } results.Add(result); // optional SMA if (smaPeriod != null && bd.Index >= lookbackPeriod + smaPeriod - 1) { decimal sumSma = 0m; for (int p = (int)bd.Index - (int)smaPeriod; p < bd.Index; p++) { sumSma += (decimal)results[p].StdDev; } result.Sma = sumSma / smaPeriod; } } return(results); }
private static IEnumerable <EmaResult> CalcEma(IEnumerable <BasicData> basicData, int lookbackPeriod) { // clean quotes basicData = Cleaners.PrepareBasicData(basicData); // validate parameters ValidateEma(basicData, lookbackPeriod); // initialize List <EmaResult> results = new List <EmaResult>(); // initialize EMA decimal k = 2 / (decimal)(lookbackPeriod + 1); decimal lastEma = basicData .Where(x => x.Index <= lookbackPeriod) .ToList() .Select(x => x.Value) .Average(); // roll through history foreach (BasicData h in basicData) { EmaResult result = new EmaResult { Index = (int)h.Index, Date = h.Date }; if (h.Index > lookbackPeriod) { result.Ema = lastEma + k * (h.Value - lastEma); lastEma = (decimal)result.Ema; } else if (h.Index == lookbackPeriod) { result.Ema = lastEma; } results.Add(result); } return(results); }
private static IEnumerable <StdDevResult> CalcStdDev(IEnumerable <BasicData> basicData, int lookbackPeriod) { // clean data basicData = Cleaners.PrepareBasicData(basicData); // validate inputs ValidateStdDev(basicData, lookbackPeriod); // initialize results List <StdDevResult> results = new List <StdDevResult>(); decimal? prevValue = null; // roll through history and compute lookback standard deviation foreach (BasicData h in basicData) { StdDevResult result = new StdDevResult { Index = (int)h.Index, Date = h.Date, }; if (h.Index >= lookbackPeriod) { // price based double[] period = basicData .Where(x => x.Index > (h.Index - lookbackPeriod) && x.Index <= h.Index) .Select(x => (double)x.Value) .ToArray(); result.StdDev = (decimal)Functions.StdDev(period); result.ZScore = (h.Value - (decimal)period.Average()) / result.StdDev; } results.Add(result); prevValue = h.Value; } return(results); }
private static IEnumerable <RsiResult> CalcRsi(IEnumerable <BasicData> basicData, int lookbackPeriod = 14) { // clean data List <BasicData> bdList = Cleaners.PrepareBasicData(basicData).ToList(); // check parameters ValidateRsi(basicData, lookbackPeriod); // initialize decimal lastValue = bdList[0].Value; decimal avgGain = 0m; decimal avgLoss = 0m; List <RsiResult> results = new List <RsiResult>(); // roll through history for (int i = 0; i < bdList.Count; i++) { BasicData h = bdList[i]; RsiResult r = new RsiResult { Index = (int)h.Index, Date = h.Date, Gain = (h.Value > lastValue) ? h.Value - lastValue : 0, Loss = (h.Value < lastValue) ? lastValue - h.Value : 0 }; results.Add(r); lastValue = h.Value; // calculate RSI if (h.Index > lookbackPeriod + 1) { avgGain = (avgGain * (lookbackPeriod - 1) + r.Gain) / lookbackPeriod; avgLoss = (avgLoss * (lookbackPeriod - 1) + r.Loss) / lookbackPeriod; if (avgLoss > 0) { decimal rs = avgGain / avgLoss; r.Rsi = 100 - (100 / (1 + rs)); } else { r.Rsi = 100; } } // initialize average gain else if (h.Index == lookbackPeriod + 1) { decimal sumGain = 0; decimal sumLoss = 0; for (int p = 0; p < lookbackPeriod; p++) { RsiResult d = results[p]; sumGain += d.Gain; sumLoss += d.Loss; } avgGain = sumGain / lookbackPeriod; avgLoss = sumLoss / lookbackPeriod; r.Rsi = (avgLoss > 0) ? 100 - (100 / (1 + (avgGain / avgLoss))) : 100; } } return(results); }
private static IEnumerable <RsiResult> CalcRsi(IEnumerable <BasicData> basicData, int lookbackPeriod = 14) { // clean data List <BasicData> bdList = Cleaners.PrepareBasicData(basicData).ToList(); // check parameters ValidateRsi(basicData, lookbackPeriod); // initialize decimal lastValue = bdList[0].Value; List <RsiResult> results = new List <RsiResult>(); // load gain data for (int i = 0; i < bdList.Count; i++) { BasicData h = bdList[i]; RsiResult result = new RsiResult { Index = (int)h.Index, Date = h.Date, Gain = (h.Value > lastValue) ? h.Value - lastValue : 0, Loss = (h.Value < lastValue) ? lastValue - h.Value : 0 }; results.Add(result); lastValue = h.Value; } // initialize average gain decimal avgGain = results.Where(x => x.Index <= lookbackPeriod).Select(g => g.Gain).Average(); decimal avgLoss = results.Where(x => x.Index <= lookbackPeriod).Select(g => g.Loss).Average(); // initial first record decimal lastRSI = (avgLoss > 0) ? 100 - (100 / (1 + (avgGain / avgLoss))) : 100; RsiResult first = results.Where(x => x.Index == lookbackPeriod + 1).FirstOrDefault(); first.Rsi = lastRSI; // calculate RSI foreach (RsiResult r in results.Where(x => x.Index > (lookbackPeriod + 1))) { avgGain = (avgGain * (lookbackPeriod - 1) + r.Gain) / lookbackPeriod; avgLoss = (avgLoss * (lookbackPeriod - 1) + r.Loss) / lookbackPeriod; if (avgLoss > 0) { decimal rs = avgGain / avgLoss; r.Rsi = 100 - (100 / (1 + rs)); } else { r.Rsi = 100; } lastRSI = (decimal)r.Rsi; } return(results); }
private static IEnumerable <RsiResult> CalcRsi(IEnumerable <BasicData> basicData, int lookbackPeriod = 14) { // clean data basicData = Cleaners.PrepareBasicData(basicData); // check parameters ValidateRsi(basicData, lookbackPeriod); // initialize decimal lastValue = basicData.First().Value; List <RsiResult> results = new List <RsiResult>(); // load gain data foreach (BasicData h in basicData) { RsiResult result = new RsiResult { Index = (int)h.Index, Date = h.Date, Gain = (h.Value > lastValue) ? h.Value - lastValue : 0, Loss = (h.Value < lastValue) ? lastValue - h.Value : 0 }; results.Add(result); lastValue = h.Value; } // initialize average gain decimal avgGain = results.Where(x => x.Index <= lookbackPeriod).Select(g => g.Gain).Average(); decimal avgLoss = results.Where(x => x.Index <= lookbackPeriod).Select(g => g.Loss).Average(); // initial first record decimal lastRSI = (avgLoss > 0) ? 100 - (100 / (1 + (avgGain / avgLoss))) : 100; bool? lastIsIncreasing = null; RsiResult first = results.Where(x => x.Index == lookbackPeriod + 1).FirstOrDefault(); first.Rsi = lastRSI; // calculate RSI foreach (RsiResult r in results.Where(x => x.Index > (lookbackPeriod + 1)).OrderBy(d => d.Index)) { avgGain = (avgGain * (lookbackPeriod - 1) + r.Gain) / lookbackPeriod; avgLoss = (avgLoss * (lookbackPeriod - 1) + r.Loss) / lookbackPeriod; if (avgLoss > 0) { decimal rs = avgGain / avgLoss; r.Rsi = 100 - (100 / (1 + rs)); } else { r.Rsi = 100; } if (r.Rsi > lastRSI) { r.IsIncreasing = true; } else if (r.Rsi < lastRSI) { r.IsIncreasing = false; } else { // no change, keep trend r.IsIncreasing = lastIsIncreasing; } lastRSI = (decimal)r.Rsi; lastIsIncreasing = r.IsIncreasing; } return(results); }