如何用LINQ按间隔(OHLC条)对时间序列进行分组



我以前见过关于这个问题的不同版本,但是没有一个明确的答案。

我有一个带有时间戳(股票交易数据,或'ticks')的对象列表:

Class Tick
{
  Datetime Timestamp;
  double Price;
}
  1. 我想根据这些值生成另一个列表,这些值按一定的间隔分组以创建OHLC条(Open, High, Low, Close)。这些条形图可以是指定的任意间隔(1分钟、5分钟、10分钟甚至1小时)。

  2. 我还需要找到一种有效的方法来将新的"tick"排序到列表中,因为它们

希望对此有任何想法,谢谢!

我想生成另一个基于对这些值进行分组一定的间隔,以便创建一个OHLC条(开、高、低、关)。这些小节可以是任意间隔的指定(1分钟、5分钟、10分钟甚至1分钟)小时)。

遗憾的是,您没有指定:

  1. bar系列的相位是什么
  2. 条的开始/结束时间是否纯粹基于"自然时间"(仅依赖于固定的时间表,而不是其中第一个和最后一个刻度的时间戳)。

假设在自然时间内,相位通常夹紧到午夜。所以小时酒吧是00:00 - 01:00,01:00 - 02:00,等等。在这种情况下,bar的开始/结束时间可以作为它的唯一键。

那么问题就变成了:一个tick的时间戳属于哪个bar- begin/end时间?如果我们假设我上面所假设的一切,那么用一些简单的整数数学就可以很容易地解决这个问题。查询可以是这样的(未经测试,仅限算法):

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)
           };

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

我还需要找到一个有效的方法将新的"勾号"排序到列表中,如它们可能会以很高的速率到达(3-5)

这取决于你的意思。

如果这些刻度来自实时价格反馈(按时间顺序),您根本不需要查找-只需存储当前的,不完整的,"部分"条。当一个新的tick到达时,检查它的时间戳。如果它仍然是当前"部分"条形图的一部分,只需用新信息更新条形图(即Close = tick)。Price, High = Max(oldHigh, tick.Price)等)。否则,"部分"栏就完成了-将其推入您的栏集。请注意,如果你使用的是"自然时间"柱状图,则柱状图的结束也可能是由时间的流逝而不是由价格事件引起的(例如,小时柱状图在整点完成)。

编辑:

否则,您将需要进行查找。如果您在排序列表中存储栏(按begin-time/end-time键),那么您只需要计算与tick相关的栏begin-time/end-time。这应该很容易;我已经给出了一个示例,说明如何在上面的LINQ查询中实现这一点。

例如:

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

相关内容

  • 没有找到相关文章