如何使用 LINQ 按时间间隔(OHLC 条)对时间序列进行分组
我以前见过这个问题的不同版本,但没有明确的答案。
我有一个带有时间戳的对象列表(股票交易数据或“报价”):
Class Tick
{
Datetime Timestamp;
double Price;
}
我想根据按特定间隔分组的那些值生成另一个列表 创建 OHLC 柱(开盘价、最高价、最低价、收盘价)。 这些条可以是指定的任何间隔(1 分钟、5、10 甚至 1 小时)。
我还需要找到一种有效的方法将新的“刻度”排序到列表中,因为它们 可能会以高速率到达(每秒 3-5 个刻度)。
对此有任何想法将不胜感激,谢谢!
I've seen variation on this question before, but without a definite answer.
I have a list of object with a timestamp (stock trades data, or 'ticks'):
Class Tick
{
Datetime Timestamp;
double Price;
}
I want to generate another list based on those values which is grouped by certain interval
in order to create an OHLC bar (Open, High, Low, Close).
These bars may be of any interval specified (1 minute, 5, 10 or even 1 hour).I also need to find an efficient way to sort new "ticks" into the list, as they
may arrive at high rate (3-5 ticks per second).
Would appreciate any thoughts on this, Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不幸的是,您还没有指定:
假设自然时间日内柱线,相位通常固定为午夜。因此,每小时的柱线将为 00:00 - 01:00、01:00 - 02:00 等。在这种情况下,柱线的开始/结束时间可以作为其唯一键。
那么问题就变成了:报价的时间戳属于哪个柱开始/结束时间?如果我们假设上面假设的一切,那么可以通过一些简单的整数数学轻松解决。然后,查询可以类似于(未经测试,仅算法):
通常希望通过索引/日期时间定位柱形图以及按时间顺序枚举系列中的所有柱形图。在这种情况下,您可能需要考虑将条形图存储在一个集合中,例如
SortedList
(其中键是条形图的开始或结束时间),它将填充所有这些角色很好。这取决于你的意思。
如果这些价格变动来自实时喂价(按时间顺序),您根本不需要查找 - 只需存储当前的、不完整的“部分”柱线即可。当新的蜱虫到达时,检查它的时间戳。如果它仍然是当前“部分”柱的一部分,只需使用新信息更新柱(即 Close = tick.Price、High = Max(oldHigh、tick.Price) 等)。否则,“部分”栏已完成 - 将其推入您的栏集合中。请注意,如果您使用“自然时间”柱,则柱的结束也可能由时间的流逝而不是价格事件引起(例如,每小时的柱在整点完成)。
编辑:
否则,您需要进行查找。如果您将条形存储在排序列表中(按开始时间/结束时间作为键),就像我上面提到的那样,那么您只需要计算与关联的条形开始时间/结束时间一个勾。那应该很容易;我已经为您提供了如何在上面的 LINQ 查询中完成此操作的示例。
例如:
Unfortunately, you haven't specified:
Assuming natural-time intra-day bars, the phases are usually clamped to midnight. So hourly bars will be 00:00 - 01:00, 01:00 - 02:00, etc. In this case, the begin / end-time of a bar can serve as its unique-key.
So then the problem becomes: To what bar- begin / end time does a tick's timestamp belong to? If we assume everything I've assumed above, that can be solved easily with some simple integer math. The query can then be something like (untested, algo only):
It's common to want to locate a bar by index / date-time as well as to enumerate all bars in a series chronologically. In this case, you might want to consider storing the bars in a collection such as a
SortedList<DateTime, Bar>
(where the key is a bar's begin or end time), which will fill all these roles nicely.It depends on what you mean.
If these ticks are coming off a live price-feed (chronologically), you don't need a look-up at all - just store the current, incomplete, "partial" bar. When a new tick arrives, inspect its timestamp. If it is still part of the current "partial" bar, just update the bar with the new information (i.e. Close = tick.Price, High = Max(oldHigh, tick.Price) etc.). Otherwise, the "partial" bar is done - push it into your bar-collection. Do note that if you are using "natural-time" bars, the end of a bar could also be brought on by the passage of time rather than by a price-event (e.g. an hourly bar completes on the hour).
EDIT:
Otherwise, you'll need to do a lookup. If you're storing in the bars in a sorted-list (keyed by begin-time / end-time) as I've mentioned above, then you'll just need to calculate the bar begin-time / end-time associated with a tick. That should be easy enough; I've already given you a sample of how you might accomplish that in the LINQ query above.
For example: