public static IEnumerable<Point> Calculate(ShareDay[] days, int periods = 14) { // Plus/minus directional movements var dmPoints = CalculateDirectionalMovement(days).ToArray(); // Emas of directional movement var positiveDmEma = Ema.Calculate(dmPoints, p => p.DateTime, p => p.PositiveDm, periods, simpleMultiplier: true).ToArray(); var negativeDmEma = Ema.Calculate(dmPoints, p => p.DateTime, p => p.NegativeDm, periods, simpleMultiplier: true).ToArray(); var atr = Atr.Calculate(days, periods, 0, pad: false, includeFirstTrueRange: false).ToArray(); // Plus/minus directional indicator var positiveDi = positiveDmEma.ZipEnds(atr, (ema, a) => Model.Point.With(ema.DateTime, 100 * ema.Value / a.Value)).ToArray(); var negativeDi = negativeDmEma.ZipEnds(atr, (ema, a) => Model.Point.With(ema.DateTime, 100 * ema.Value / a.Value)).ToArray(); // Directional index var dx = positiveDi.Zip(negativeDi, (p, n) => Model.Point.With(p.DateTime, 100 * Math.Abs(p.Value - n.Value) / Math.Abs(p.Value + n.Value))).ToArray(); // Average directional index var adx = Ema.Calculate(dx, p => p.DateTime, p => p.Value, periods, simpleMultiplier: true).ToArray(); for (int i = 0, j = periods - 1; i < adx.Length; i++, j++) { yield return new Point { DateTime = adx[i].DateTime, Adx = adx[i].Value, NegativeDi = negativeDi[j].Value, PositiveDi = positiveDi[j].Value }; } }
/// <summary> /// Returns TR array of length [days.Length] /// </summary> public static IEnumerable<Point<decimal>> Calculate(ShareDay[] days, int startIndex, bool includeFirstTrueRange) { if (startIndex >= days.Length) yield break; var previous = days[startIndex]; if (includeFirstTrueRange) yield return Point.With(previous.Date, previous.High - previous.Low); for (int i = startIndex + 1; i < days.Length; i++) { var current = days[i]; var trueRange = new[] { current.High - current.Low, Math.Abs(current.High - previous.Close), Math.Abs(current.Low - previous.Close) }.Max(); yield return Point.With(current.Date, trueRange); previous = current; } }
public Share ParseFile(string filePath) { using (var csv = new StreamReader(filePath)) { var share = new Share(); var row = 0; var days = new List<ShareDay>(); while (!csv.EndOfStream) { var cells = csv.ReadLine().Split(','); Debug.Assert(cells.Length == 9); var day = new ShareDay(); day.Date = DateTime.ParseExact(cells[2], "yyyyMMdd", CultureInfo.CurrentCulture); day.Open = Decimal.Parse(cells[3]); day.High = Decimal.Parse(cells[4]); day.Low = Decimal.Parse(cells[5]); day.Close = Decimal.Parse(cells[6]); day.Volume = UInt32.Parse(cells[7]); day.OpenInt = UInt16.Parse(cells[8]); days.Add(day); row++; } share.Days = days.ToArray(); return share; } }
private ShareDay ReadDay(int row, BinaryReader reader) { var bytes = reader.ReadBytes(34); using (var r = GetReader(new MemoryStream(bytes))) { var day = new ShareDay(); day.Bytes = bytes; day.Row = row; day.Tf = ReadTf(r); day.Unknown1 = r.ReadByte(); Assert(day.Unknown1 == 0); day.Date = ReadDate(r); day.Open = (decimal)r.ReadSingle(); day.High = (decimal)r.ReadSingle(); day.Low = (decimal)r.ReadSingle(); day.Close = (decimal)r.ReadSingle(); day.Volume = r.ReadUInt32(); day.OpenInt = r.ReadUInt16(); day.Unknown2 = r.ReadBytes(2); Assert(day.Unknown2.Sum(b => b) == 0); return day; } }
public static IEnumerable<Point<decimal>> Calculate(ShareDay[] days, int shortPeriods, int longPeriods) { var longEma = Ema.Calculate(days, longPeriods).ToList(); var shortEma = Ema.Calculate(days, shortPeriods).Skip(longPeriods - shortPeriods).ToList(); Debug.Assert(longEma.Count == shortEma.Count); return shortEma.Select((t, i) => Point.With(t.DateTime, t.Value - longEma[i].Value)); }
/// <summary> /// Returns ATR array of length [days.Length - nSmoothingPeriods + 1] /// </summary> public static IEnumerable<Point<decimal>> Calculate(ShareDay[] days, int nSmoothingPeriods, int startIndex, bool pad, bool includeFirstTrueRange = true) { if (startIndex < 0 || startIndex + nSmoothingPeriods > days.Length) return Enumerable.Empty<Point<Decimal>>(); var trueRanges = TrueRange.Calculate(days, startIndex, includeFirstTrueRange).ToArray(); return Ema.Calculate(trueRanges, tr => tr.DateTime, tr => tr.Value, nSmoothingPeriods, pad: pad, simpleMultiplier: true); }
/// <summary> /// Returns directional movement array of length [days.Length - 1] /// </summary> public static IEnumerable<DirectionalMovementPoint> CalculateDirectionalMovement(ShareDay[] days) { for (int i = 1; i < days.Length; i++) { var upMove = days[i].High - days[i - 1].High; var downMove = days[i - 1].Low - days[i].Low; var positiveDm = upMove > downMove && upMove > 0 ? upMove : 0; var negativeDm = downMove > upMove && downMove > 0 ? downMove : 0; yield return new DirectionalMovementPoint { DateTime = days[i].Date, PositiveDm = positiveDm, NegativeDm = negativeDm }; } }
/// <summary> /// Returns %R array of length [days.Length - periods + 1] /// </summary> public static IEnumerable<Point<decimal>> Calculate(ShareDay[] days, int periods) { return days .FullWindow(periods) .Select(w => { var min = w.Min(d => d.Low); var max = w.Max(d => d.High); var last = w.Last(); return Point.With(last.Date, (max - last.Close) / (max - min) * -100); }); }
/// <summary> /// Returns trading band array of length [days.Length - periods + 1] /// </summary> public static IEnumerable<Point> Calculate(ShareDay[] days, int periods, decimal plusMinusPercentage) { var sma = Sma.Calculate(days, periods); var tradingBand = sma.Select(p => new Point { DateTime = p.DateTime, Indicator = p.Value, Upper = (p.Value*(100 + plusMinusPercentage))/100, Lower = (p.Value*(100 - plusMinusPercentage))/100 }); return tradingBand; }
public IEnumerable<Point<decimal>> Calculate(ShareDay[] days, Parameters p) { return Calculate(days, p.SignalEmaPeriods, p.ShortEmaPeriods, p.LongEmaPeriods); }
public static IEnumerable<Point<decimal>> Calculate(ShareDay[] days, int signalPeriods = 9, int shortPeriods = 12, int longPeriods = 26) { var macd = Macd.Calculate(days, shortPeriods, longPeriods).ToArray(); var signalLine = MacdSignalLine.Calculate(macd, signalPeriods).ToArray(); return macd.ZipEnds(signalLine, (m, s) => Point.With(m.DateTime, m.Value - s.Value)); }
public IEnumerable<Point<decimal>> Calculate(ShareDay[] days, Parameters p, int startIndex, bool pad) { return Calculate(days, p.NSmoothingPeriods, startIndex, pad, includeFirstTrueRange: true); }
public static IEnumerable<Point<uint>> Calculate(ShareDay[] days) { return days.Select(d => Point.With<uint>(d.Date, d.Volume)); }
public IEnumerable<Point<decimal>> Calculate(ShareDay[] days, Parameters p) { return Calculate(days, p.Periods); }
public IEnumerable<Point> Calculate(ShareDay[] days, Parameters p) { return Calculate(days, p.Periods, p.PlusMinusPercentage); }
public static IEnumerable<Point> Calculate(ShareDay[] days) { return days.Select(d => new Point { DateTime = d.Date, Open = d.Open, High = d.High, Low = d.Low, Close = d.Close }); }