【问题标题】:How to group a time series by interval (OHLC bars) with LINQ如何使用 LINQ 按间隔(OHLC 条)对时间序列进行分组
【发布时间】:2011-08-14 19:00:33
【问题描述】:

我之前看到过这个问题的变化,但没有明确的答案。

我有一个带有时间戳的对象列表(股票交易数据或“报价”):

Class Tick
{
  Datetime Timestamp;
  double Price;
}
  1. 我想根据按一定间隔分组的值生成另一个列表 为了创建一个 OHLC 柱(开盘价、最高价、最低价、收盘价)。 这些条可以是任何指定的时间间隔(1 分钟、5、10 甚至 1 小时)。

  2. 我还需要找到一种有效的方法将新的“刻度”排序到列表中,因为它们 可能会以很高的速度到达(每秒 3-5 个滴答声)。

如果对此有任何想法,将不胜感激,谢谢!

【问题讨论】:

  • 你能举一个输入和预期输出的例子吗?

标签: c# linq group-by


【解决方案1】:

我想生成另一个基于 在那些被分组的值上 一定的间隔,以创建一个 OHLC 柱(开盘价、最高价、最低价、收盘价)。 这些条可以是任何间隔 指定(1 分钟、5、10 甚至 1 小时)。

很遗憾,您没有指定:

  1. 条形系列的阶段将是什么。
  2. 柱形图的开始/结束时间是否纯粹基于“自然时间”(仅取决于固定时间表,而不是其中第一个和最后一个刻度的时间戳)。

假设自然时间的日内柱线,相位通常被限制在午夜。所以每小时柱将是 00:00 - 01:00、01:00 - 02:00 等。在这种情况下,柱的开始/结束时间可以用作其唯一键。

那么问题就变成了:tick 的时间戳属于哪个条形开始/结束时间?如果我们假设我在上面假设的所有内容,那么可以通过一些简单的整数数学轻松解决。然后查询可以类似于(未经测试,仅限算法):

var bars = from tick in ticks

           // Calculate the chronological, natural-time, intra-day index 
           // of the bar associated with a tick.
           let barIndexForDay = tick.Timestamp.TimeOfDay.Ticks / barSizeInTicks

           // Calculate the begin-time of the bar associated with a tick.
           // For example, turn 2011/04/28 14:23.45 
           // into 2011/04/28 14:20.00, assuming 5 min bars.
           let barBeginDateTime = tick.Timestamp.Date.AddTicks
                              (barIndexForDay * barSizeInTicks)

           // Produce raw tick-data for each bar by grouping.
           group tick by barBeginDateTime into tickGroup

           // Order prices for a group chronologically.
           let orderedPrices = tickGroup.OrderBy(t => t.Timestamp)
                                        .Select(t => t.Price)

           select new Bar
           {
                Open = orderedPrices.First(),
                Close = orderedPrices.Last(),
                High = orderedPrices.Max(),
                Low = orderedPrices.Min(),
                BeginTime = tickGroup.Key,
                EndTime = tickGroup.Key.AddTicks(barSizeInTicks)
           };

通常希望按索引/日期时间定位条形图以及按时间顺序枚举系列中的所有条形图。在这种情况下,您可能需要考虑将条形图存储在一个集合中,例如 SortedList<DateTime, Bar>(其中的键是条形图的开始时间或结束时间),这样可以很好地满足所有这些角色。

我还需要找到一种有效的方法 将新的“刻度”排序到列表中,如 他们可能会以很高的速度到达(3-5 每秒滴答声)。

这取决于你的意思。

如果这些分时来自实时价格馈送(按时间顺序),您根本不需要查找 - 只需存储当前的、不完整的“部分”柱。当一个新的刻度到达时,检查它的时间戳。如果它仍然是当前“部分”柱的一部分,只需使用新信息更新柱(即 Close = tick.Price、High = Max(oldHigh, tick.Price) 等)。否则,“部分”栏已完成 - 将其推入您的栏集。请注意,如果您使用的是“自然时间”柱,则柱的结束也可能是随着时间的推移而不是价格事件(例如,每小时柱在整点完成)。

编辑:

否则,您需要进行查找。如果您存储在排序列表中的条形图中(按开始时间/结束时间键入),那么您只需要计算与关联的条形开始时间/结束时间一个勾号。这应该很容易;我已经在上面的 LINQ 查询中为您提供了一个示例,说明如何实现这一点。

例如:

myBars[GetBeginTime(tick.Timestamp)].Update(tick);

【讨论】:

  • 谢谢,但我不确定刻度是否按时间顺序排列,如果不重新计算整个列表,您将如何解决此问题?
  • 另外,我认为这不适用于多天的图表
  • @Saul:它将工作多天 - 该组的密钥将tick.Timestamp.Date 考虑在内。
  • 你的回答给了我一些不错的想法。感谢您分享您的想法。 (:
猜你喜欢
  • 2011-03-01
  • 1970-01-01
  • 2021-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-02
  • 1970-01-01
相关资源
最近更新 更多