Как сгруппировать временной ряд по интервалу (бары OHLC) с помощью LINQ - PullRequest
1 голос
/ 28 апреля 2011

Я видел вариации на этот вопрос раньше, но без определенного ответа.

У меня есть список объектов с отметкой времени (данные по биржевым сделкам или «тики»):

Class Tick
{
  Datetime Timestamp;
  double Price;
}
  1. Я хочу создать другой список на основе тех значений, которые сгруппированы по определенному интервалу для того, чтобы создать бар OHLC (Open, High, Low, Close). Эти столбцы могут иметь любой указанный интервал (1 минута, 5, 10 или даже 1 час).

  2. Мне также нужно найти эффективный способ сортировки новых «галочек» в списке, так как они может достигать высокой скорости (3-5 тиков в секунду).

Буду признателен за любые мысли по этому поводу, спасибо!

1 Ответ

1 голос
/ 28 апреля 2011

Я хочу создать другой список на основе на те значения, которые сгруппированы по определенный интервал для того, чтобы создать Бар 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) и т. Д.). В противном случае «частичная» полоса готова - вставьте ее в свою коллекцию. Обратите внимание, что если вы используете бары «естественного времени», то конец бара также может быть вызван течением времени, а не ценовым событием (например, почасовой бар завершается в час).

EDIT:

В противном случае вам нужно будет выполнить поиск. Если вы храните столбцы в отсортированном списке (с указанием времени начала / окончания), как я уже упоминал выше, вам просто нужно рассчитать время начала / окончания бара, связанное с галочка Это должно быть достаточно легко; Я уже дал вам пример того, как вы могли бы сделать это в запросе LINQ выше.

Например:

myBars[GetBeginTime(tick.Timestamp)].Update(tick);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...