using System.Collections.Generic;
var source = new List<TickData>()
new() {Timestamp = DateTime.Parse("2020-01-02 04:00:02.100"), Price = 294.00D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:00:32.680"), Price = 296.00D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:00:36.263"), Price = 295.08D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:00:42.090"), Price = 295.08D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:00:42.127"), Price = 295.08D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:00:46.357"), Price = 295.02D, Volume = 500},
new() {Timestamp = DateTime.Parse("2020-01-02 04:00:46.357"), Price = 292.00D, Volume = 500},
new() {Timestamp = DateTime.Parse("2020-01-02 04:00:46.598"), Price = 295.02D, Volume = 500},
new() {Timestamp = DateTime.Parse("2020-01-02 04:00:47.168"), Price = 295.02D, Volume = 500},
new() {Timestamp = DateTime.Parse("2020-01-02 04:00:47.914"), Price = 295.02D, Volume = 500},
new() {Timestamp = DateTime.Parse("2020-01-02 04:00:48.290"), Price = 295.02D, Volume = 500},
new() {Timestamp = DateTime.Parse("2020-01-02 04:00:49.391"), Price = 295.02D, Volume = 500},
new() {Timestamp = DateTime.Parse("2020-01-02 04:00:49.854"), Price = 295.02D, Volume = 500},
new() {Timestamp = DateTime.Parse("2020-01-02 04:00:49.854"), Price = 295.02D, Volume = 500},
new() {Timestamp = DateTime.Parse("2020-01-02 04:00:50.024"), Price = 295.99D, Volume = 500},
new() {Timestamp = DateTime.Parse("2020-01-02 04:01:22.893"), Price = 295.2D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:02:36.026"), Price = 295.21D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:02:43.101"), Price = 295.21D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:02:46.025"), Price = 295.2D, Volume = 1900},
new() {Timestamp = DateTime.Parse("2020-01-02 04:02:46.526"), Price = 295.21D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:02:46.527"), Price = 295.2D, Volume = 1900},
new() {Timestamp = DateTime.Parse("2020-01-02 04:02:54.163"), Price = 295.21D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:02:56.029"), Price = 295.2D, Volume = 1900},
new() {Timestamp = DateTime.Parse("2020-01-02 04:02:56.370"), Price = 295.21D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:02:56.371"), Price = 295.2D, Volume = 1900},
new() {Timestamp = DateTime.Parse("2020-01-02 04:02:56.530"), Price = 295.21D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:03:34.546"), Price = 295.41D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:04:27.331"), Price = 295.41D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:04:35.805"), Price = 295.35D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:06:34.495"), Price = 295.37D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:06:48.211"), Price = 295.37D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:06:48.857"), Price = 295.37D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:06:52.385"), Price = 295.37D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:06:57.519"), Price = 295.37D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:07:14.514"), Price = 295.55D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:07:15.370"), Price = 295.41D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:08:14.167"), Price = 295.55D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:08:14.167"), Price = 295.41D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:08:16.583"), Price = 295.41D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:08:16.590"), Price = 295.41D, Volume = 200},
new() {Timestamp = DateTime.Parse("2020-01-02 04:08:18.260"), Price = 295.41D, Volume = 200},
new() {Timestamp = DateTime.Parse("2020-01-02 04:08:18.857"), Price = 295.41D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:08:20.425"), Price = 295.41D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:08:22.247"), Price = 295.41D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:09:19.030"), Price = 295.5D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:09:54.711"), Price = 295.5D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:10:10.505"), Price = 295.5D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:10:54.926"), Price = 295.5D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:11:01.927"), Price = 295.5D, Volume = 1100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:11:58.106"), Price = 295.41D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:12:09.706"), Price = 295.41D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:12:14.453"), Price = 295.41D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:12:38.186"), Price = 295.41D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:13:10.196"), Price = 295.52D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:13:58.690"), Price = 295.49D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:14:03.660"), Price = 295.45D, Volume = 100},
new() {Timestamp = DateTime.Parse("2020-01-02 04:14:35.205"), Price = 295.45D, Volume = 100}
var period = TimeSpan.FromMinutes(5);
var stats = source.Select(d => new
Period = d.Timestamp.Ticks / period.Ticks
Timestamp = new DateTime(period.Ticks*(int)g.Min(d=>d.Period)),
Open = g.OrderBy(s => s.Timestamp).First().Price,
Close = g.OrderBy(s => s.Timestamp).Last().Price,
Low = g.Min(d => d.Price),
High = g.Max(d => d.Price),
Volume=g.Sum(s=>s.Volume)
foreach (var ohlc in stats)
Console.WriteLine($"T:{ohlc.Timestamp:s} O:{ohlc.Open:N2}, H:{ohlc.High:N2}, C:{ohlc.Close:N2}, L:{ohlc.Low:N2}, V:{ohlc.Volume}");
public DateTime Timestamp { get; init; }
public double Price { get; init; }
public int Volume { get; init; }
public void Deconstruct(out DateTime Timestamp, out double Price, out int Volume)
Timestamp = this.Timestamp;
public DateTime Timestamp { get; set; }
public double Open { get; set; }
public double Close { get; set; }
public double Low { get; set; }
public double High { get; set; }
public int Volume { get; set; }