2011-04-28 55 views
1

我以前见过在这个问题上的变化,但没有一个明确的答案。如何按时间间隔(OHLC条)时间序列与LINQ

我有对象的具有时间戳的列表(股票交易数据,或“蜱”):

Class Tick 
{ 
    Datetime Timestamp; 
    double Price; 
} 
  1. 我要生成基于其通过一定的时间间隔分组的那些值的另一个列表 为了创建一个OHLC栏(打开,高,低,关闭)。 这些栏可以是指定的任何间隔(1分钟,5,10或甚至1小时)。

  2. 我还需要找到一种有效的方法来将新的“滴答”分类到列表中,因为它们可能以高速率(每秒3-5滴)到达。

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

+0

可不可以给输入和预期输出的例子吗? – 2011-04-28 14:53:05

回答

0

我要生成基于其通过 一定的间隔,以创造一个 OHLC杆(打开,高,低,关闭)分组的那些值 另一个列表。 这些杆可以是指定的任何间隔 的(1分钟,5个,10个或甚至1 小时)。

不幸的是,你还没有指定:

  1. 酒吧系列的阶段将是什么。
  2. 无论是酒吧的开始/结束时间是完全基于“自然时间”(只依靠一个固定的时间表,而不是第一个和最后一个蜱在它的时间戳)或没有。

假设天然白天酒吧,阶段是通常夹到午夜。所以每小时的酒吧将是00:00 - 01:00,01:00 - 02:00等。在这种情况下,酒吧的开始/结束时间可以作为其独特的关键。

那么接下来的问题就变成:在什么酒吧,开始/结束时间不打勾的时间戳属于哪一种?如果我们假设我上面假设的一切,那么可以用一些简单的整数数学来轻松解决。然后,查询可以是这样的(未经测试,只是算法中):

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); 
+0

谢谢,但我不确定蜱是否可能按时间顺序排列,如何在不重新计算整个列表的情况下处理此问题? – Saul 2011-04-28 15:34:18

+0

此外,我认为这将不会在多天的图表上工作 – Saul 2011-04-28 15:37:11

+0

@Saul:它可以工作多天 - 该组的关键考虑了'tick.Timestamp.Date'。 – Ani 2011-04-28 15:39:01