我之前看到过这个问题的变异,但没有明确的答案。
我有一个带有时间戳的对象列表(股票交易数据或'滴答'):
Class Tick
{
Datetime Timestamp;
double Price;
}
我想基于那些按特定间隔分组的值生成另一个列表 为了创建一个OHLC栏(开放,高,低,关闭)。 这些条可以是指定的任何间隔(1分钟,5,10或甚至1小时)。
我还需要找到一种有效的方法来将新的“滴答”排序到列表中,就像它们一样 可能会以很高的速度到达(每秒3-5个滴答)。
对此有任何想法,谢谢!
答案 0 :(得分:1)
我想基于另一个列表生成 在那些按分组的值上 一定的间隔,以创造一个 OHLC栏(开盘价,最高价,最低价,收盘价)。 这些条可以是任何间隔 指定(1分钟,5,10或甚至1) 小时)。
很遗憾,您尚未指定:
假设自然时间日内条形,通常将 夹紧到午夜。所以每小时的酒吧将是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);