2011-04-28 53 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