Создание цифровых фильтров, не запаздывающих по времени

Konstantin Gruzdev | 10 января, 2014

Введение

В статье рассматривается один из подходов к определению полезного сигнала (тенденции) потоковых данных. Небольшие практические тесты фильтрации (сглаживания) биржевых котировок демонстрируют потенциальную возможность создания цифровых фильтров (индикаторов), которые не запаздывают по времени и не перерисовываются на последних барах.


Обычный подход

Этот подход основан на классических методах сглаживания временных рядов. Об этом есть множество статей, как на этом ресурсе, так и на других. Результаты получаем тоже классические:

  1. Смена тенденции проявляется с запаздыванием;
  2. За увеличение реакции индикатора (цифрового фильтра) приходится платить снижением качества сглаживания;
  3. Попытки реализации не запаздывающих индикаторов приводят к их перерисовке на последних отсчетах (барах).

Если трейдеры научились с этим бороться, используя инерционность экономических процессов и другие хитрости, то при оценке экспериментальных данных в реальном времени, например при испытании авиационных конструкций, это неприемлемо.


Основная проблема

Не секрет, что большинство торговых систем с течением времени перестают работать. Или то, что индикаторы только на некоторых участках показательны. Объяснение этому простое: рыночные котировки нестационарны. Простое определение стационарности процесса есть в Википедии:

Стационарность — свойство процесса не менять свои характеристики со временем. Имеет смысл в нескольких разделах науки.

Судя по определению, методы анализа стационарных временных рядов не имеют смысла в техническом анализе. Оно и понятно, как только мы посчитаем характеристики известного ряда биржевых котировок, в рынок войдет хитрый маркетмейкер и сделает наши расчеты бессмысленными.

Несмотря на очевидность этого факта, огромное количество индикаторов строятся на основе теории анализа стационарных временных рядов. Примером таких индикаторов являются скользящие средние и их модификации. Есть, правда, попытки создания адаптивных индикаторов. Вроде как они должны в той или иной степени учитывать нестационарность биржевых котировок, но что-то чуда не происходит. Попытки "наказать" маркетмейкера, используя известные на сегодня способы анализа нестационарных рядов (вейвлеты, эмпирические моды и другие), тоже не приводят к успеху. Похоже на то, что упускается некий ключевой фактор.

Основная причина такого положения дел заключается в том, что используемые методы не предназначены для работы с потоковыми данными. Все они (или почти все) разрабатывались для анализа уже известных данных или, в терминологии технического анализа, исторических данных. Эти способы удобны, например, в геофизике: "тряхнул" землю, получил сейсмограмму и потом пару месяцев ее изучаешь. То есть они приемлемы там, где возникающие при фильтрации неопределенности на концах временного ряда несущественно влияют на конечный результат.

При анализе экспериментальных потоковых данных или биржевых котировок максимальный интерес представляет не история, а последние поступившие данные. Именно те данные, с которыми не умеют работать классические алгоритмы.


Кластерный фильтр

Кластерный фильтр (англ. cluster — гроздь, сгусток, пучок) - совокупность цифровых фильтров, аппроксимирующих исходную последовательность. Кластерный фильтр не стоит путать с кластерными индикаторами.

Кластерный фильтр удобно использовать для анализа нестационарных временных рядов в реальном времени, иными словами - потоковых данных. Это значит, что наибольший интерес такой фильтр представляет, например, не для сглаживания уже известных значений временного ряда, а для получения наиболее вероятного сглаженного значения нового данного, полученного в реальном времени.

В отличие от всевозможных методов декомпозиции (разложения на составляющие) или просто фильтров нужной частоты, кластерные фильтры создают композицию или веер вероятных значений исходного ряда, которые в дальнейшем подвергаются дополнительному анализу для аппроксимации исходной последовательности. Входная последовательность больше играет роль ориентира, чем то, что анализируют. Основному анализу подвергают значения, посчитанные набором фильтров после обработки поступившего данного.

Рисунок 1. Схема простого кластерного фильтра

Рисунок 1. Схема простого кластерного фильтра

В общем случае каждый фильтр, включенный в кластер, обладает своими индивидуальными характеристиками и никак не связан с другими. Иногда эти фильтры настроены для анализа некого своего стационарного временного ряда, который описывает отдельные свойства исходного нестационарного. В самом простом случае, если исходный нестационарный ряд меняет свои параметры, то происходит "переключение" между фильтрами. Таким образом, кластерный фильтр отслеживает изменение характеристик в реальном времени.


Порядок построения кластерных фильтров

Любой кластерный фильтр может быть создан в три этапа:

1. Чаще всего первый этап самый сложный, но именно на этом этапе формируются вероятностные модели получаемых потоковых данных. Этих моделей может быть сколь угодно много. Они не всегда имеют отношение к физическим процессам, которые влияют на аппроксимируемые данные. Чем более точно модели описывают аппроксимируемую последовательность, тем больше вероятность получить не запаздывающий по времени кластерный фильтр.

2. На втором этапе под каждую модель создается один или несколько цифровых фильтров. Самое общее условие объединения фильтров в кластер служит то, что они принадлежат моделям, описывающих аппроксимируемую последовательность.

3. Итак, мы можем иметь от одного и более фильтров в кластере. Соответственно, на каждом новом отсчете у нас есть величина самого отсчета и одно или более значений фильтров. Таким образом, на каждом отсчете у нас есть вектор или искусственный шум из нескольких значений (минимум два). Все, что теперь нужно сделать, так это выбрать наиболее подходящее значение.


Пример простого кластерного фильтра

Для примера реализуем простой кластерный фильтр, соответствующий схеме, изображенной на рисунке 1. В качестве входной последовательности возьмем котировки. Можно взять просто цены закрытия любого таймфрейма.

1. Описание принятой модели. Будем исходить из следующих предположений:

2. Подбираем цифровые фильтры. Для простоты возьмем два фильтра:

3. Выбираем наиболее подходящее значение для кластерного фильтра.

Итак, на каждом новом отсчете будем иметь значение самого отсчета (цена закрытия), значение MA и EMA. Цену закрытия будем игнорировать, исходя из второго условия нашей модели. Далее выбираем значение МА или ЕМА, исходя из последнего условия модели, то есть из условия следования тренду:

Здесь:


Программный код и результат работы кластерного фильтра

Код индикатора с нашим кластерным фильтром не сложнее кода скользящего среднего. Поэтому здесь его разбирать не имеет смысла, там нет какого-то ноу-хау. Исходник приложен к статье.

Не теряя времени, пример работы нашего индикатора можно посмотреть на видео:


Видео 1. Результат работы простого кластерного фильтра

Несмотря на то, что создание фильтра было похоже на легкое колдовство, чем на строгий математический подход, на видео хорошо заметно, что линия кластерного фильтра ведет себя адекватнее отдельно взятых скользящих средних. Особенно это видно на пилообразных участках исходного ряда. Если кого-то не впечатлило, то еще, например, можно сравнить с JJMA, который считается одним из лучших индикаторов. На следующем видео тот же участок, но на нем состязаются JJMA и наш фильтр. Параметры JJMA постарался подобрать так, чтобы его линия по максимуму совпадала с нашим индикатором.

Видео 2. Сравнение простого кластерного фильтра и JJMA

В среднем, наш фильтр не проигрывает JJMA на любых таймсериях. Но если из JJMA уже не получить что-то лучшее, то наш кластерный фильтр можно улучшить.


Эффект опережающего сглаживания

До сих пор не было никакого подтверждения, что кластерные фильтры способны сглаживать исходную последовательность без запаздывания. Для достижения подобного результата требуется создание более сложного фильтра, чем тот, который мы рассмотрели выше.

Для демонстрации был сделан индикатор GMomentum test. Он содержит две индикаторных линии:

В настройках индикатора есть различные варианты тестов, которые специально подготовлены для статьи. В описанных ниже тестах используется относительный моментум как у Уильяма Блау. Для своих экспериментов можете использовать другие вариации моментума, результаты будут такими же. Подробное описание, инструкции по установке и использованию индикатора найдете в описании самого индикатора.

Какого-то особого аргумента в пользу выбора Momentum для статьи у меня нет, просто линия моментума достаточно сильно зашумлена и поэтому работа фильтра, на мой взгляд, наиболее показательна. В общем, запускаете индикатор GMomentum test и изучаете, как ведет себя красная линия в сравнении с синей.

Для начала рассмотрим один любопытный момент. Для этого при запуске индикатора необходимо установить параметр "Filter" в "Test No.1 Advance". В этом режиме настройки фильтра таковы, что достаточно часто проявляется эффект, который можно назвать опережающим. При тестировании вы не увидите сглаживания всей исходной линии моментума. Фильтр выискивает участки, где есть вероятность получить опережающий эффект. Не удивительно, что это получается не всегда. Но достаточно часто, чтобы можно было это заметить.

На графике ниже представлен один из показательных участков работы фильтра.

Рисунок 2. Опережающий эффект при сглаживании линии моментума

Рисунок 2. Опережающий эффект при сглаживании линии моментума

Стоит отметить, что это только видимость опережающей фильтрации. Эта видимость возникает исключительно из-за присутствующих шумовых движений самой линии моментума, а не потому, что фильтр опередил время. Подобные исследования других индикаторов (от простого MA до JJMA) подтверждают, что эффект опережающего сглаживания можно наблюдать на каждом из них. И чем меньше установленный период, тем чаще это проявляется. Последние наработки показывают, что эффект можно усилить. Все зависит только от способа формирования вектора вероятных значений и его анализа.


Эффект кобры

Тот, кто уже видел индикатор в работе, мог обратить внимание еще на одну аномалию. Линия индикатора на последнем незавершенном баре не всегда следует за ценой. Например, цена может расти, а индикатор движется вниз. И наоборот. При быстром рынке или в визуализаторе это порой напоминает язычок кобры, которым она нащупывает путь к добыче.

Видео 3. Опережающее сглаживание и эффект кобры


Ошибки, опережающие тенденцию

Выше было показано, что когда исходная линия моментума ошибается (шумит) против тенденции, то это приводит к эффекту опережения исходной линии сглаженной линией. Очевидно, что линия моментума может ошибаться и в другую сторону, то есть неожиданно проскочить далеко в направлении тенденции, и даже неприлично долго задерживаться там, хотя тренд уже развернулся. Будет логичным, если фильтр начнет притормаживать такие движения.

Давайте посмотрим, как работает алгоритм при фильтрации вот таких опережающих тенденцию ошибок. Для этого при запуске индикатора необходимо установить параметр "Filter" в "Test No.2 Smoothing". Работа кластерного фильтра во время этого теста разделена на две части.

В коротком имени индикатора "GMomentum(Параметр 1, Параметр 2)", отображаемом в подокне графика, в скобках есть два параметра. Если второй параметр равен -1, то происходит попытка исправить (сгладить) ошибки, опережающие тенденцию. Если второй параметр равен или выше нуля, то подключаются настройки для получения опережающего сглаживания.

На видео ниже можно увидеть работу фильтра при изменении его чувствительности от минимума до приемлемого значения и обратно. В индикаторе для управления чувствительностью (при активном окне индикатора) нажимайте клавиши Up и Down, чтобы добиться подобного эффекта как на видео.

Видео 4. Фильтрация ошибок, опережающих тенденцию.

На видео сверху видно, что, несмотря на резкие движения цены и исходной линии моментума, сглаживание линии моментума при увеличении чувствительности фильтра происходит без задержки. При максимальном сглаживании получаем приемлемые точки входа.

Кстати, флэтовые участки являются бедой большинства индикаторов. Здесь же, даже при этих настройках, некоторые из них легко вырождаются почти в прямую линию. Теоретически, используя эту методику, можно улучшить любой из существующих индикаторов без создания дополнительного запаздывания. Практически - нужно проверять.

На следующем видео обратите внимание на то, что фильтр "съедает" сильные пики исходной линии моментума и практически без запаздывания отрисовывает тенденцию, которая, к слову, близка к движению цены и более гладкая. Объяснение, почему это так, есть в статье про индикаторы Уильяма Блау.

Видео 5. Сглаживание пиков исходной линии моментума.

Полученный результат не на всей истории котировок такой впечатляющий. Но учитывая тот факт, что моментум обладает большими шумовыми движениями и то, что индикатор делался всего-навсего для демонстрации фильтрации потоковых данных без задержки по времени, можно считать его вполне приемлемым. В дополнение стоит отметить, что индикатор не перерисовывается.


Импульсная характеристика

Исследования характеристик моментума со встроенным фильтром могут оказаться весьма занятными. Например, импульсная характеристика хорошо демонстрирует, как и куда исчезают пики на линии индикатора. Для теста необходимо установить параметр "Filter" в "Test No.3 Impulse". Во время теста на каждом 1024 баре подается единичный импульс. После старта индикатора найдите этот момент на графике. Он должен выглядеть так:

Рисунок 3. Импульсная характеристика моментума

Рисунок 3. Импульсная характеристика моментума

При запуске индикатора фильтр отключен. Поэтому вы увидите два пика на синей и красной линии. Один пик будет в момент единичного импульса и равен ему, другой - направлен в обратную сторону через указанное количество периодов. Именно так выглядит импульсная характеристика "голого" моментума. Далее, с помощью клавиш Up и Down постепенно увеличивайте или уменьшайте чувствительность фильтра. У вас должно получиться нечто подобное:

Видео 6. Импульсная характеристика моментума

Как видите, фильтр постепенно под корень "съедает" второй пик и абсолютно не трогает первый. Фильтр полностью исправляет то, что натворил моментум и в точности воссоздает исходную картину: единичный импульс в чистом поле. Нет никакого запаздывания. Нет искажения амплитуды единичного импульса и его формы. Что это? Работа идеального фильтра?


Идеальный фильтр

Есть один существенный фактор, который не позволяет сходу считать рассматриваемый фильтр идеальным. Но об этом чуть ниже.

Существует фиксированная идея, что идеального фильтра не может быть. Что все фильтры (индикаторы) запаздывают. Тогда как объяснить полученные результаты? Все они представлены как то, что можно наблюдать. Хитрая работа программиста? Пожалуй, можно схитрить в коде с единичным импульсом. Но ведь это все проявляется на любых котировках. При этом нет необходимости как-то настраивать или перенастраивать индикатор под каждый торговый инструмент.

Когда мы строим фильтр из физических объектов (конденсатор, индуктивность и т.п.), идеального фильтра не может быть. Об этом хорошо позаботилась сама природа. Но когда мы имеем дело с цифровым миром, то разве построение идеального фильтра не возможно? Естественно, что ответ нужно давать, пренебрегая физическими ограничениями вычислительных систем (точность, скорость расчета и т.п.).

Вернемся к нашему индикатору. Встроенный цифровой фильтр не относится к линейным. И то, что выше названо импульсной характеристикой, для индикатора со встроенным фильтром просто удачный частный случай фильтрации. Для того чтобы делать какие-либо далеко идущие выводы, нужно провести более корректное и тщательное исследование.


Заключение

Надеюсь, что материал, представленный в статье, разрушит некоторые стереотипы в отношении построения цифровых фильтров (индикаторов).

Все, что описано, можно исследовать с помощью предложенных индикаторов. Представленная версия GMomentum test позволит всем оценить работоспособность и потенциальные возможности кластерных фильтров. А простой пример фильтра может подтолкнуть разработчиков на создание своих.

В завершении, возьму на себя смелость сделать следующий вывод: создание полноценных не запаздывающих по времени индикаторов (цифровых фильтров) потенциально возможно.